Merge tag 'v3.2-rc7' into staging/for_v3.3

Linux 3.2-rc7

* tag 'v3.2-rc7': (1304 commits)
  Linux 3.2-rc7
  netfilter: xt_connbytes: handle negation correctly
  Btrfs: call d_instantiate after all ops are setup
  Btrfs: fix worker lock misuse in find_worker
  net: relax rcvbuf limits
  rps: fix insufficient bounds checking in store_rps_dev_flow_table_cnt()
  net: introduce DST_NOPEER dst flag
  mqprio: Avoid panic if no options are provided
  bridge: provide a mtu() method for fake_dst_ops
  md/bitmap: It is OK to clear bits during recovery.
  md: don't give up looking for spares on first failure-to-add
  md/raid5: ensure correct assessment of drives during degraded reshape.
  md/linear: fix hot-add of devices to linear arrays.
  sparc64: Fix MSIQ HV call ordering in pci_sun4v_msiq_build_irq().
  pata_of_platform: Add missing CONFIG_OF_IRQ dependency.
  ipv4: using prefetch requires including prefetch.h
  VFS: Fix race between CPU hotplug and lglocks
  vfs: __read_cache_page should use gfp argument rather than GFP_KERNEL
  USB: Fix usb/isp1760 build on sparc
  net: Add a flow_cache_flush_deferred function
  ...

Conflicts:
	drivers/media/common/tuners/tda18218.c
	drivers/media/video/omap3isp/ispccdc.c
	drivers/staging/media/as102/as102_drv.h
diff --git a/Documentation/DocBook/media/dvb/dvbproperty.xml b/Documentation/DocBook/media/dvb/dvbproperty.xml
index 3bc8a61..ffee1fb 100644
--- a/Documentation/DocBook/media/dvb/dvbproperty.xml
+++ b/Documentation/DocBook/media/dvb/dvbproperty.xml
@@ -334,9 +334,10 @@
 		<title>fe_delivery_system type</title>
 		<para>Possible values: </para>
 <programlisting>
+
 typedef enum fe_delivery_system {
 	SYS_UNDEFINED,
-	SYS_DVBC_ANNEX_AC,
+	SYS_DVBC_ANNEX_A,
 	SYS_DVBC_ANNEX_B,
 	SYS_DVBT,
 	SYS_DSS,
@@ -353,6 +354,7 @@
 	SYS_DAB,
 	SYS_DVBT2,
 	SYS_TURBO,
+	SYS_DVBC_ANNEX_C,
 } fe_delivery_system_t;
 </programlisting>
 		</section>
@@ -647,6 +649,18 @@
 			many data types via a single multiplex. The API will soon support this
 			at which point this section will be expanded.</para>
 	</section>
+	<section id="DTV_ENUM_DELSYS">
+		<title><constant>DTV_ENUM_DELSYS</constant></title>
+		<para>A Multi standard frontend needs to advertise the delivery systems provided.
+			Applications need to enumerate the provided delivery systems, before using
+			any other operation with the frontend. Prior to it's introduction,
+			FE_GET_INFO was used to determine a frontend type. A frontend which
+			provides more than a single delivery system, FE_GET_INFO doesn't help much.
+			Applications which intends to use a multistandard frontend must enumerate
+			the delivery systems associated with it, rather than trying to use
+			FE_GET_INFO. In the case of a legacy frontend, the result is just the same
+			as with FE_GET_INFO, but in a more structured format </para>
+	</section>
 </section>
 	<section id="frontend-property-terrestrial-systems">
 	<title>Properties used on terrestrial delivery systems</title>
@@ -767,7 +781,8 @@
 	<title>Properties used on cable delivery systems</title>
 	<section id="dvbc-params">
 		<title>DVB-C delivery system</title>
-		<para>The DVB-C Annex-A/C is the widely used cable standard. Transmission uses QAM modulation.</para>
+		<para>The DVB-C Annex-A is the widely used cable standard. Transmission uses QAM modulation.</para>
+		<para>The DVB-C Annex-C is optimized for 6MHz, and is used in Japan. It supports a subset of the Annex A modulation types, and a roll-off of 0.13, instead of 0.15</para>
 		<para>The following parameters are valid for DVB-C Annex A/C:</para>
 		<itemizedlist mark='opencircle'>
 			<listitem><para><link linkend="DTV-API-VERSION"><constant>DTV_API_VERSION</constant></link></para></listitem>
diff --git a/Documentation/DocBook/media/dvb/frontend.xml b/Documentation/DocBook/media/dvb/frontend.xml
index 61407ea..28d7ea5 100644
--- a/Documentation/DocBook/media/dvb/frontend.xml
+++ b/Documentation/DocBook/media/dvb/frontend.xml
@@ -45,8 +45,8 @@
   </row>
   <row>
      <entry id="FE_QAM"><constant>FE_QAM</constant></entry>
-     <entry>For DVB-C annex A/C standard</entry>
-     <entry><constant>SYS_DVBC_ANNEX_AC</constant></entry>
+     <entry>For DVB-C annex A standard</entry>
+     <entry><constant>SYS_DVBC_ANNEX_A</constant></entry>
   </row>
   <row>
      <entry id="FE_OFDM"><constant>FE_OFDM</constant></entry>
diff --git a/Documentation/DocBook/media/v4l/biblio.xml b/Documentation/DocBook/media/v4l/biblio.xml
index afc8a0d..cea6fd3 100644
--- a/Documentation/DocBook/media/v4l/biblio.xml
+++ b/Documentation/DocBook/media/v4l/biblio.xml
@@ -178,11 +178,3 @@
     </biblioentry>
 
   </bibliography>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/common.xml b/Documentation/DocBook/media/v4l/common.xml
index a86f7a0..9d39198 100644
--- a/Documentation/DocBook/media/v4l/common.xml
+++ b/Documentation/DocBook/media/v4l/common.xml
@@ -1195,11 +1195,3 @@
     <para>These ioctls are optional, drivers need not implement
 them. If so, they return the &EINVAL;.</para>
   </section>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml
index b68698f..8b44a43 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -1082,7 +1082,7 @@
 follow SGI's lead, and adopt a multimedia timestamping system like
 their UST (Unadjusted System Time). See
 http://web.archive.org/web/*/http://reality.sgi.com
-/cpirazzi_engr/lg/time/intro.html. 
+/cpirazzi_engr/lg/time/intro.html.
 UST uses timestamps that are 64-bit signed integers
 (not struct timeval's) and given in nanosecond units. The UST clock
 starts at zero when the system is booted and runs continuously and
@@ -2507,11 +2507,3 @@
       </itemizedlist>
     </section>
   </section>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index 3bc5ee8..c0422c6 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -3329,6 +3329,16 @@
 		  <entry>The short circuit protection of the flash
 		  controller has been triggered.</entry>
 		</row>
+		<row>
+		  <entry><constant>V4L2_FLASH_FAULT_OVER_CURRENT</constant></entry>
+		  <entry>Current in the LED power supply has exceeded the limit
+		  specific to the flash controller.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_FLASH_FAULT_INDICATOR</constant></entry>
+		  <entry>The flash controller has detected a short or open
+		  circuit condition on the indicator LED.</entry>
+		</row>
 	      </tbody>
 	    </entrytbl>
 	  </row>
@@ -3357,11 +3367,3 @@
 
     </section>
 </section>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "common.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/dev-capture.xml b/Documentation/DocBook/media/v4l/dev-capture.xml
index 2237c66..e1c5f94 100644
--- a/Documentation/DocBook/media/v4l/dev-capture.xml
+++ b/Documentation/DocBook/media/v4l/dev-capture.xml
@@ -108,11 +108,3 @@
 linkend="userp">user pointer</link>) I/O. See <xref
 linkend="io" /> for details.</para>
   </section>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/dev-codec.xml b/Documentation/DocBook/media/v4l/dev-codec.xml
index 6e156dc..dca0ecd 100644
--- a/Documentation/DocBook/media/v4l/dev-codec.xml
+++ b/Documentation/DocBook/media/v4l/dev-codec.xml
@@ -16,11 +16,3 @@
 I/O.</para>
 
   <para>[to do]</para>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/dev-effect.xml b/Documentation/DocBook/media/v4l/dev-effect.xml
index 9c243be..2350a67 100644
--- a/Documentation/DocBook/media/v4l/dev-effect.xml
+++ b/Documentation/DocBook/media/v4l/dev-effect.xml
@@ -15,11 +15,3 @@
 functions, or through the streaming I/O mechanism.</para>
 
   <para>[to do]</para>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/dev-event.xml b/Documentation/DocBook/media/v4l/dev-event.xml
index f14ae3f..19f4bec 100644
--- a/Documentation/DocBook/media/v4l/dev-event.xml
+++ b/Documentation/DocBook/media/v4l/dev-event.xml
@@ -41,11 +41,3 @@
 event you want to subscribe to whether this is applicable for that event or not.</para>
 	</listitem>
       </orderedlist></para>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/dev-osd.xml b/Documentation/DocBook/media/v4l/dev-osd.xml
index c9a68a2..479d943 100644
--- a/Documentation/DocBook/media/v4l/dev-osd.xml
+++ b/Documentation/DocBook/media/v4l/dev-osd.xml
@@ -154,11 +154,3 @@
 however the framebuffer interface of the driver may support the
 <constant>FBIOBLANK</constant> ioctl.</para>
   </section>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/dev-output.xml b/Documentation/DocBook/media/v4l/dev-output.xml
index 919e22c..9130a3d 100644
--- a/Documentation/DocBook/media/v4l/dev-output.xml
+++ b/Documentation/DocBook/media/v4l/dev-output.xml
@@ -104,11 +104,3 @@
 linkend="userp">user pointer</link>) I/O. See <xref
 linkend="io" /> for details.</para>
   </section>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/dev-overlay.xml b/Documentation/DocBook/media/v4l/dev-overlay.xml
index 92513cf..40d1d76 100644
--- a/Documentation/DocBook/media/v4l/dev-overlay.xml
+++ b/Documentation/DocBook/media/v4l/dev-overlay.xml
@@ -369,11 +369,3 @@
     <para>To start or stop the frame buffer overlay applications call
 the &VIDIOC-OVERLAY; ioctl.</para>
   </section>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/dev-radio.xml b/Documentation/DocBook/media/v4l/dev-radio.xml
index 73aa90b..3e6ac73 100644
--- a/Documentation/DocBook/media/v4l/dev-radio.xml
+++ b/Documentation/DocBook/media/v4l/dev-radio.xml
@@ -47,11 +47,3 @@
 &VIDIOC-G-MODULATOR; ioctl
 reports the supported frequency range.</para>
   </section>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
- -->
diff --git a/Documentation/DocBook/media/v4l/dev-raw-vbi.xml b/Documentation/DocBook/media/v4l/dev-raw-vbi.xml
index c5a70bd..b788c72 100644
--- a/Documentation/DocBook/media/v4l/dev-raw-vbi.xml
+++ b/Documentation/DocBook/media/v4l/dev-raw-vbi.xml
@@ -337,11 +337,3 @@
 unavailable, for example the device is already in use by another
 process.</para>
   </section>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/dev-rds.xml b/Documentation/DocBook/media/v4l/dev-rds.xml
index 2427f54..38883a4 100644
--- a/Documentation/DocBook/media/v4l/dev-rds.xml
+++ b/Documentation/DocBook/media/v4l/dev-rds.xml
@@ -29,10 +29,10 @@
 will set the <constant>V4L2_TUNER_CAP_RDS</constant> flag in
 the <structfield>capability</structfield> field of &v4l2-tuner;.  If
 the driver only passes RDS blocks without interpreting the data
-the <constant>V4L2_TUNER_SUB_RDS_BLOCK_IO</constant> flag has to be
+the <constant>V4L2_TUNER_CAP_RDS_BLOCK_IO</constant> flag has to be
 set, see <link linkend="reading-rds-data">Reading RDS data</link>.
 For future use the
-flag <constant>V4L2_TUNER_SUB_RDS_CONTROLS</constant> has also been
+flag <constant>V4L2_TUNER_CAP_RDS_CONTROLS</constant> has also been
 defined. However, a driver for a radio tuner with this capability does
 not yet exist, so if you are planning to write such a driver you
 should discuss this on the linux-media mailing list: &v4l-ml;.</para>
@@ -52,9 +52,9 @@
 In order to enable the RDS transmission one must set the <constant>V4L2_TUNER_SUB_RDS</constant>
 bit in the <structfield>txsubchans</structfield> field of &v4l2-modulator;.
 If the driver only passes RDS blocks without interpreting the data
-the <constant>V4L2_TUNER_SUB_RDS_BLOCK_IO</constant> flag has to be set. If the
+the <constant>V4L2_TUNER_CAP_RDS_BLOCK_IO</constant> flag has to be set. If the
 tuner is capable of handling RDS entities like program identification codes and radio
-text, the flag <constant>V4L2_TUNER_SUB_RDS_CONTROLS</constant> should be set,
+text, the flag <constant>V4L2_TUNER_CAP_RDS_CONTROLS</constant> should be set,
 see <link linkend="writing-rds-data">Writing RDS data</link> and
 <link linkend="fm-tx-controls">FM Transmitter Control Reference</link>.</para>
   </section>
@@ -194,11 +194,3 @@
       </tgroup>
     </table>
   </section>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
- -->
diff --git a/Documentation/DocBook/media/v4l/dev-sliced-vbi.xml b/Documentation/DocBook/media/v4l/dev-sliced-vbi.xml
index 69e789f..548f8ea 100644
--- a/Documentation/DocBook/media/v4l/dev-sliced-vbi.xml
+++ b/Documentation/DocBook/media/v4l/dev-sliced-vbi.xml
@@ -697,12 +697,3 @@
 
   </section>
   </section>
-
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
- -->
diff --git a/Documentation/DocBook/media/v4l/dev-teletext.xml b/Documentation/DocBook/media/v4l/dev-teletext.xml
index 414b1cf..bd21c64 100644
--- a/Documentation/DocBook/media/v4l/dev-teletext.xml
+++ b/Documentation/DocBook/media/v4l/dev-teletext.xml
@@ -27,11 +27,3 @@
 
   <para>Modern devices all use the <link linkend="raw-vbi">raw</link> or
 <link linkend="sliced">sliced</link> VBI API.</para>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/driver.xml b/Documentation/DocBook/media/v4l/driver.xml
index 1f7eea5..eacafe3 100644
--- a/Documentation/DocBook/media/v4l/driver.xml
+++ b/Documentation/DocBook/media/v4l/driver.xml
@@ -198,11 +198,3 @@
     <para>to do</para>
   </section>
 -->
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/func-close.xml b/Documentation/DocBook/media/v4l/func-close.xml
index dfb41cb..232920d 100644
--- a/Documentation/DocBook/media/v4l/func-close.xml
+++ b/Documentation/DocBook/media/v4l/func-close.xml
@@ -60,11 +60,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/func-ioctl.xml b/Documentation/DocBook/media/v4l/func-ioctl.xml
index 2de64be..4394184 100644
--- a/Documentation/DocBook/media/v4l/func-ioctl.xml
+++ b/Documentation/DocBook/media/v4l/func-ioctl.xml
@@ -69,11 +69,3 @@
     the parameter remains unmodified.</para>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/func-mmap.xml b/Documentation/DocBook/media/v4l/func-mmap.xml
index 786732b..f31ad71 100644
--- a/Documentation/DocBook/media/v4l/func-mmap.xml
+++ b/Documentation/DocBook/media/v4l/func-mmap.xml
@@ -181,11 +181,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/func-munmap.xml b/Documentation/DocBook/media/v4l/func-munmap.xml
index e2c4190..860d49c 100644
--- a/Documentation/DocBook/media/v4l/func-munmap.xml
+++ b/Documentation/DocBook/media/v4l/func-munmap.xml
@@ -74,11 +74,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/func-open.xml b/Documentation/DocBook/media/v4l/func-open.xml
index 7595d07..cf64e20 100644
--- a/Documentation/DocBook/media/v4l/func-open.xml
+++ b/Documentation/DocBook/media/v4l/func-open.xml
@@ -111,11 +111,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/func-poll.xml b/Documentation/DocBook/media/v4l/func-poll.xml
index ec3c718..85cad8b 100644
--- a/Documentation/DocBook/media/v4l/func-poll.xml
+++ b/Documentation/DocBook/media/v4l/func-poll.xml
@@ -117,11 +117,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/func-read.xml b/Documentation/DocBook/media/v4l/func-read.xml
index a5089bf..e218bbf 100644
--- a/Documentation/DocBook/media/v4l/func-read.xml
+++ b/Documentation/DocBook/media/v4l/func-read.xml
@@ -179,11 +179,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/func-select.xml b/Documentation/DocBook/media/v4l/func-select.xml
index b671362..e12a60d 100644
--- a/Documentation/DocBook/media/v4l/func-select.xml
+++ b/Documentation/DocBook/media/v4l/func-select.xml
@@ -128,11 +128,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/func-write.xml b/Documentation/DocBook/media/v4l/func-write.xml
index 2c09c09..5752078 100644
--- a/Documentation/DocBook/media/v4l/func-write.xml
+++ b/Documentation/DocBook/media/v4l/func-write.xml
@@ -126,11 +126,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml
index 3f47df1..b815929 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -1282,11 +1282,3 @@
 	</mediaobject>
     </figure>
   </section>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/libv4l.xml b/Documentation/DocBook/media/v4l/libv4l.xml
index 3cb10ec..d3b71e2 100644
--- a/Documentation/DocBook/media/v4l/libv4l.xml
+++ b/Documentation/DocBook/media/v4l/libv4l.xml
@@ -158,10 +158,3 @@
 	</section>
 
 </section>
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-grey.xml b/Documentation/DocBook/media/v4l/pixfmt-grey.xml
index 3b72bc6..bee970d 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-grey.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-grey.xml
@@ -60,11 +60,3 @@
 	</example>
       </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-m420.xml b/Documentation/DocBook/media/v4l/pixfmt-m420.xml
index ce4bc019..aadae92 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-m420.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-m420.xml
@@ -137,11 +137,3 @@
 	</example>
       </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-nv12.xml b/Documentation/DocBook/media/v4l/pixfmt-nv12.xml
index 873f670..84dd4fd 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-nv12.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-nv12.xml
@@ -141,11 +141,3 @@
 	</example>
       </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml b/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml
index c9e166d..3fd3ce5 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml
@@ -144,11 +144,3 @@
 	</example>
       </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-nv12mt.xml b/Documentation/DocBook/media/v4l/pixfmt-nv12mt.xml
index 7a2855a..2f82b1d 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-nv12mt.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-nv12mt.xml
@@ -64,11 +64,3 @@
 	</example>
       </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-nv16.xml b/Documentation/DocBook/media/v4l/pixfmt-nv16.xml
index 2609403..8ae1f8a8 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-nv16.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-nv16.xml
@@ -164,11 +164,3 @@
 	</example>
       </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-packed-rgb.xml b/Documentation/DocBook/media/v4l/pixfmt-packed-rgb.xml
index 4db272b..ba56536 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-packed-rgb.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-packed-rgb.xml
@@ -930,11 +930,3 @@
 
   </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-packed-yuv.xml b/Documentation/DocBook/media/v4l/pixfmt-packed-yuv.xml
index 3cab5d0..33fa5a4 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-packed-yuv.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-packed-yuv.xml
@@ -234,11 +234,3 @@
 
   </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-sbggr16.xml b/Documentation/DocBook/media/v4l/pixfmt-sbggr16.xml
index 519a9ef..6494b05 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-sbggr16.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-sbggr16.xml
@@ -81,11 +81,3 @@
     </example>
   </refsect1>
 </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-sbggr8.xml b/Documentation/DocBook/media/v4l/pixfmt-sbggr8.xml
index 5fe84ec..5eaf2b4 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-sbggr8.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-sbggr8.xml
@@ -65,11 +65,3 @@
 	</example>
       </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-sgbrg8.xml b/Documentation/DocBook/media/v4l/pixfmt-sgbrg8.xml
index d67a472..fee65dc 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-sgbrg8.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-sgbrg8.xml
@@ -65,11 +65,3 @@
 	</example>
       </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-sgrbg8.xml b/Documentation/DocBook/media/v4l/pixfmt-sgrbg8.xml
index 0cdf13b..19727ab 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-sgrbg8.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-sgrbg8.xml
@@ -65,11 +65,3 @@
 	</example>
       </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-uyvy.xml b/Documentation/DocBook/media/v4l/pixfmt-uyvy.xml
index 816c8d4..b1f6801 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-uyvy.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-uyvy.xml
@@ -118,11 +118,3 @@
 	</example>
       </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-vyuy.xml b/Documentation/DocBook/media/v4l/pixfmt-vyuy.xml
index 61f12a5..8280340 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-vyuy.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-vyuy.xml
@@ -118,11 +118,3 @@
 	</example>
       </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-y16.xml b/Documentation/DocBook/media/v4l/pixfmt-y16.xml
index d584040..ff4f727 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-y16.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-y16.xml
@@ -79,11 +79,3 @@
     </example>
   </refsect1>
 </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-y41p.xml b/Documentation/DocBook/media/v4l/pixfmt-y41p.xml
index 73c8536..98dcb91 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-y41p.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-y41p.xml
@@ -147,11 +147,3 @@
 	</example>
       </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-yuv410.xml b/Documentation/DocBook/media/v4l/pixfmt-yuv410.xml
index 8eb4a19..0869dce 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-yuv410.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-yuv410.xml
@@ -131,11 +131,3 @@
 	</example>
       </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-yuv411p.xml b/Documentation/DocBook/media/v4l/pixfmt-yuv411p.xml
index 00e0960..086dc73 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-yuv411p.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-yuv411p.xml
@@ -145,11 +145,3 @@
 	</example>
       </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-yuv420.xml b/Documentation/DocBook/media/v4l/pixfmt-yuv420.xml
index 42d7de5..48649fa 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-yuv420.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-yuv420.xml
@@ -147,11 +147,3 @@
 	</example>
       </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml b/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml
index f5d8f57..9957863 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml
@@ -152,11 +152,3 @@
 	</example>
       </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-yuv422p.xml b/Documentation/DocBook/media/v4l/pixfmt-yuv422p.xml
index 4348bd9..4ce6463 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-yuv422p.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-yuv422p.xml
@@ -151,11 +151,3 @@
 	</example>
       </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-yuyv.xml b/Documentation/DocBook/media/v4l/pixfmt-yuyv.xml
index bdb2ffa..58384092 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-yuyv.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-yuyv.xml
@@ -118,11 +118,3 @@
 	</example>
       </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt-yvyu.xml b/Documentation/DocBook/media/v4l/pixfmt-yvyu.xml
index 40d17ae..bfffdc7 100644
--- a/Documentation/DocBook/media/v4l/pixfmt-yvyu.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt-yvyu.xml
@@ -118,11 +118,3 @@
 	</example>
       </refsect1>
     </refentry>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "pixfmt.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/pixfmt.xml b/Documentation/DocBook/media/v4l/pixfmt.xml
index 2ff6b77..a33a4b2 100644
--- a/Documentation/DocBook/media/v4l/pixfmt.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt.xml
@@ -997,11 +997,3 @@
       </tgroup>
     </table>
   </section>
-
-  <!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
-  -->
diff --git a/Documentation/DocBook/media/v4l/vidioc-enum-dv-presets.xml b/Documentation/DocBook/media/v4l/vidioc-enum-dv-presets.xml
index 1d31427..0be17c2 100644
--- a/Documentation/DocBook/media/v4l/vidioc-enum-dv-presets.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-enum-dv-presets.xml
@@ -228,11 +228,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/vidioc-enum-fmt.xml b/Documentation/DocBook/media/v4l/vidioc-enum-fmt.xml
index 71d373b..347d142 100644
--- a/Documentation/DocBook/media/v4l/vidioc-enum-fmt.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-enum-fmt.xml
@@ -156,11 +156,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/vidioc-enuminput.xml b/Documentation/DocBook/media/v4l/vidioc-enuminput.xml
index 476fe1d..9b8efcd 100644
--- a/Documentation/DocBook/media/v4l/vidioc-enuminput.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-enuminput.xml
@@ -311,11 +311,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/vidioc-enumoutput.xml b/Documentation/DocBook/media/v4l/vidioc-enumoutput.xml
index a281d26..a64d5ef 100644
--- a/Documentation/DocBook/media/v4l/vidioc-enumoutput.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-enumoutput.xml
@@ -196,11 +196,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/vidioc-enumstd.xml b/Documentation/DocBook/media/v4l/vidioc-enumstd.xml
index 95803fe..3a5fc54 100644
--- a/Documentation/DocBook/media/v4l/vidioc-enumstd.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-enumstd.xml
@@ -381,11 +381,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-ctrl.xml b/Documentation/DocBook/media/v4l/vidioc-g-ctrl.xml
index 5146d00..12b1d05 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-ctrl.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-ctrl.xml
@@ -127,11 +127,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml b/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml
index 5122ce8..6f1f9a6 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml
@@ -312,10 +312,3 @@
   </refsect1>
 </refentry>
 
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml b/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml
index 0557182..93817f3 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-fbuf.xml
@@ -295,7 +295,8 @@
 	    <entry>The device is capable of non-destructive overlays.
 When the driver clears this flag, only destructive overlays are
 supported. There are no drivers yet which support both destructive and
-non-destructive overlays.</entry>
+non-destructive overlays. Video Output Overlays are in practice always
+non-destructive.</entry>
 	  </row>
 	  <row>
 	    <entry><constant>V4L2_FBUF_CAP_CHROMAKEY</constant></entry>
@@ -339,8 +340,8 @@
 	  <row>
 	    <entry><constant>V4L2_FBUF_CAP_SRC_CHROMAKEY</constant></entry>
 	    <entry>0x0080</entry>
-	    <entry>The device supports Source Chroma-keying. Framebuffer pixels
-with the chroma-key colors are replaced by video pixels, which is exactly opposite of
+	    <entry>The device supports Source Chroma-keying. Video pixels
+with the chroma-key colors are replaced by framebuffer pixels, which is exactly opposite of
 <constant>V4L2_FBUF_CAP_CHROMAKEY</constant></entry>
 	  </row>
 	</tbody>
@@ -356,7 +357,9 @@
 	    <entry><constant>V4L2_FBUF_FLAG_PRIMARY</constant></entry>
 	    <entry>0x0001</entry>
 	    <entry>The framebuffer is the primary graphics surface.
-In other words, the overlay is destructive. [?]</entry>
+In other words, the overlay is destructive. This flag is typically set by any
+driver that doesn't have the <constant>V4L2_FBUF_CAP_EXTERNOVERLAY</constant>
+capability and it is cleared otherwise.</entry>
 	  </row>
 	  <row>
 	    <entry><constant>V4L2_FBUF_FLAG_OVERLAY</constant></entry>
@@ -366,9 +369,8 @@
 	  </row>
 	  <row>
 	    <entry spanname="hspan">The purpose of
-<constant>V4L2_FBUF_FLAG_PRIMARY</constant> and
 <constant>V4L2_FBUF_FLAG_OVERLAY</constant> was never quite clear.
-Most drivers seem to ignore these flags. For compatibility with the
+Most drivers seem to ignore this flag. For compatibility with the
 <wordasword>bttv</wordasword> driver applications should set the
 <constant>V4L2_FBUF_FLAG_OVERLAY</constant> flag.</entry>
 	  </row>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml b/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml
index 062d720..1643181 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml
@@ -135,11 +135,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-modulator.xml b/Documentation/DocBook/media/v4l/vidioc-g-modulator.xml
index 15ce660..7f4ac7e 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-modulator.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-modulator.xml
@@ -236,11 +236,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-priority.xml b/Documentation/DocBook/media/v4l/vidioc-g-priority.xml
index 8f5e3da..6a81b4f 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-priority.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-priority.xml
@@ -133,11 +133,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-std.xml b/Documentation/DocBook/media/v4l/vidioc-g-std.xml
index 37996f2..99ff1a0 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-std.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-std.xml
@@ -88,11 +88,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml b/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml
index bd98c73..91ec2fb 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml
@@ -318,6 +318,16 @@
 	<entry>RDS capture is supported. This capability is only valid for
 radio tuners.</entry>
 	  </row>
+	  <row>
+	<entry><constant>V4L2_TUNER_CAP_RDS_BLOCK_IO</constant></entry>
+	<entry>0x0100</entry>
+	<entry>The RDS data is passed as unparsed RDS blocks.</entry>
+	  </row>
+	  <row>
+	<entry><constant>V4L2_TUNER_CAP_RDS_CONTROLS</constant></entry>
+	<entry>0x0200</entry>
+	<entry>The RDS data is parsed by the hardware and set via controls.</entry>
+	  </row>
 	</tbody>
       </tgroup>
     </table>
@@ -525,11 +535,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/vidioc-querybuf.xml b/Documentation/DocBook/media/v4l/vidioc-querybuf.xml
index 5c104d4..6e414d7 100644
--- a/Documentation/DocBook/media/v4l/vidioc-querybuf.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-querybuf.xml
@@ -100,11 +100,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/vidioc-queryctrl.xml b/Documentation/DocBook/media/v4l/vidioc-queryctrl.xml
index 0ac0057..36660d3 100644
--- a/Documentation/DocBook/media/v4l/vidioc-queryctrl.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-queryctrl.xml
@@ -443,11 +443,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml b/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml
index c30dcc4..e013da8 100644
--- a/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml
@@ -125,11 +125,3 @@
     </variablelist>
   </refsect1>
 </refentry>
-
-<!--
-Local Variables:
-mode: sgml
-sgml-parent-document: "v4l2.sgml"
-indent-tabs-mode: nil
-End:
--->
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index e67be7a..d1d4a17 100755
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -27,8 +27,8 @@
 		"or51211", "or51132_qam", "or51132_vsb", "bluebird",
 		"opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718",
 		"af9015", "ngene", "az6027", "lme2510_lg", "lme2510c_s7395",
-		"lme2510c_s7395_old", "drxk", "drxk_terratec_h5", "tda10071",
-		"it9135" );
+		"lme2510c_s7395_old", "drxk", "drxk_terratec_h5",
+		"drxk_hauppauge_hvr930c", "tda10071", "it9135", "it9137");
 
 # Check args
 syntax() if (scalar(@ARGV) != 1);
@@ -644,6 +644,24 @@
     "$fwfile"
 }
 
+sub drxk_hauppauge_hvr930c {
+    my $url = "http://www.wintvcd.co.uk/drivers/";
+    my $zipfile = "HVR-9x0_5_10_325_28153_SIGNED.zip";
+    my $hash = "83ab82e7e9480ec8bf1ae0155ca63c88";
+    my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
+    my $drvfile = "HVR-900/emOEM.sys";
+    my $fwfile = "dvb-usb-hauppauge-hvr930c-drxk.fw";
+
+    checkstandard();
+
+    wgetfile($zipfile, $url . $zipfile);
+    verify($zipfile, $hash);
+    unzip($zipfile, $tmpdir);
+    extract("$tmpdir/$drvfile", 0x117b0, 42692, "$fwfile");
+
+    "$fwfile"
+}
+
 sub drxk_terratec_h5 {
     my $url = "http://www.linuxtv.org/downloads/firmware/";
     my $hash = "19000dada8e2741162ccc50cc91fa7f1";
@@ -658,6 +676,26 @@
 }
 
 sub it9135 {
+	my $sourcefile = "dvb-usb-it9135.zip";
+	my $url = "http://www.ite.com.tw/uploads/firmware/v3.6.0.0/$sourcefile";
+	my $hash = "1e55f6c8833f1d0ae067c2bb2953e6a9";
+	my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 0);
+	my $outfile = "dvb-usb-it9135.fw";
+	my $fwfile1 = "dvb-usb-it9135-01.fw";
+	my $fwfile2 = "dvb-usb-it9135-02.fw";
+
+	checkstandard();
+
+	wgetfile($sourcefile, $url);
+	unzip($sourcefile, $tmpdir);
+	verify("$tmpdir/$outfile", $hash);
+	extract("$tmpdir/$outfile", 64, 8128, "$fwfile1");
+	extract("$tmpdir/$outfile", 12866, 5817, "$fwfile2");
+
+	"$fwfile1 $fwfile2"
+}
+
+sub it9137 {
     my $url = "http://kworld.server261.com/kworld/CD/ITE_TiVme/V1.00/";
     my $zipfile = "Driver_V10.323.1.0412.100412.zip";
     my $hash = "79b597dc648698ed6820845c0c9d0d37";
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv
index 4739d56..8948da4 100644
--- a/Documentation/video4linux/CARDLIST.bttv
+++ b/Documentation/video4linux/CARDLIST.bttv
@@ -71,7 +71,7 @@
  70 -> Prolink Pixelview PV-BT878P+ (Rev.4C,8E)
  71 -> Lifeview FlyVideo 98EZ (capture only) LR51          [1851:1851]
  72 -> Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM) [1554:4011]
- 73 -> Sensoray 311                                        [6000:0311]
+ 73 -> Sensoray 311/611                                    [6000:0311,6000:0611]
  74 -> RemoteVision MX (RV605)
  75 -> Powercolor MTV878/ MTV878R/ MTV878F
  76 -> Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP) [0e11:0079]
diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
index 8910449d..99acaa3 100644
--- a/Documentation/video4linux/CARDLIST.cx23885
+++ b/Documentation/video4linux/CARDLIST.cx23885
@@ -29,3 +29,5 @@
  28 -> LEADTEK WinFast PxTV1200                            [107d:6f22]
  29 -> GoTView X5 3D Hybrid                                [5654:2390]
  30 -> NetUP Dual DVB-T/C-CI RF                            [1b55:e2e4]
+ 31 -> Leadtek Winfast PxDVR3200 H XC4000                  [107d:6f39]
+ 32 -> MPX-885
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index d9c0f11..eee18e6 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -85,3 +85,5 @@
  84 -> Samsung SMT 7020 DVB-S                              [18ac:dc00,18ac:dccd]
  85 -> Twinhan VP-1027 DVB-S                               [1822:0023]
  86 -> TeVii S464 DVB-S/S2                                 [d464:9022]
+ 87 -> Leadtek WinFast DTV2000 H PLUS                      [107d:6f42]
+ 88 -> Leadtek WinFast DTV1800 H (XC4000)                  [107d:6f38]
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index 4a7b3df..7734b2c 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -11,7 +11,7 @@
  10 -> Hauppauge WinTV HVR 900                  (em2880)        [2040:6500]
  11 -> Terratec Hybrid XS                       (em2880)
  12 -> Kworld PVR TV 2800 RF                    (em2820/em2840)
- 13 -> Terratec Prodigy XS                      (em2880)        [0ccd:0047]
+ 13 -> Terratec Prodigy XS                      (em2880)
  14 -> SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
  15 -> V-Gear PocketTV                          (em2800)
  16 -> Hauppauge WinTV HVR 950                  (em2883)        [2040:6513,2040:6517,2040:651b]
@@ -64,7 +64,7 @@
  64 -> Easy Cap Capture DC-60                   (em2860)
  65 -> IO-DATA GV-MVP/SZ                        (em2820/em2840) [04bb:0515]
  66 -> Empire dual TV                           (em2880)
- 67 -> Terratec Grabby                          (em2860)        [0ccd:0096]
+ 67 -> Terratec Grabby                          (em2860)        [0ccd:0096,0ccd:10AF]
  68 -> Terratec AV350                           (em2860)        [0ccd:0084]
  69 -> KWorld ATSC 315U HDTV TV Box             (em2882)        [eb1a:a313]
  70 -> Evga inDtube                             (em2882)
@@ -76,3 +76,5 @@
  76 -> KWorld PlusTV 340U or UB435-Q (ATSC)     (em2870)        [1b80:a340]
  77 -> EM2874 Leadership ISDBT                  (em2874)
  78 -> PCTV nanoStick T2 290e                   (em28174)
+ 79 -> Terratec Cinergy H5                      (em2884)        [0ccd:10a2,0ccd:10ad]
+ 80 -> PCTV DVB-S2 Stick (460e)                 (em28174)
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index 7efae9b..e7ef38a 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -186,3 +186,4 @@
 185 -> MagicPro ProHDTV Pro2 DMB-TH/Hybrid      [17de:d136]
 186 -> Beholder BeholdTV 501                    [5ace:5010]
 187 -> Beholder BeholdTV 503 FM                 [5ace:5030]
+188 -> Sensoray 811/911                         [6000:0811,6000:0911]
diff --git a/Documentation/video4linux/CARDLIST.saa7164 b/Documentation/video4linux/CARDLIST.saa7164
index 152bd7b..2205e8d 100644
--- a/Documentation/video4linux/CARDLIST.saa7164
+++ b/Documentation/video4linux/CARDLIST.saa7164
@@ -7,3 +7,5 @@
   6 -> Hauppauge WinTV-HVR2200                             [0070:8901]
   7 -> Hauppauge WinTV-HVR2250                             [0070:8891,0070:8851]
   8 -> Hauppauge WinTV-HVR2250                             [0070:88A1]
+  9 -> Hauppauge WinTV-HVR2200                             [0070:8940]
+ 10 -> Hauppauge WinTV-HVR2200                             [0070:8953]
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index f8dcabf..659b2ba 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -612,6 +612,12 @@
 will be either a top-level mutex or a mutex per device node. If you want
 finer-grained locking then you have to set it to NULL and do you own locking.
 
+It is up to the driver developer to decide which method to use. However, if
+your driver has high-latency operations (for example, changing the exposure
+of a USB webcam might take a long time), then you might be better off with
+doing your own locking if you want to allow the user to do other things with
+the device while waiting for the high-latency command to finish.
+
 If a lock is specified then all file operations will be serialized on that
 lock. If you use videobuf then you must pass the same lock to the videobuf
 queue initialize function: if videobuf has to wait for a frame to arrive, then
@@ -619,6 +625,11 @@
 also waits in the code, then you should do the same to allow other processes
 to access the device node while the first process is waiting for something.
 
+In the case of videobuf2 you will need to implement the wait_prepare and
+wait_finish callbacks to unlock/lock if applicable. In particular, if you use
+the lock in struct video_device then you must unlock/lock this mutex in
+wait_prepare and wait_finish.
+
 The implementation of a hotplug disconnect should also take the lock before
 calling v4l2_device_disconnect.
 
diff --git a/MAINTAINERS b/MAINTAINERS
index 6afba60..39723f1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2837,6 +2837,14 @@
 S:	Maintained
 F:	drivers/platform/x86/fujitsu-laptop.c
 
+FUJITSU M-5MO LS CAMERA ISP DRIVER
+M:	Kyungmin Park <kyungmin.park@samsung.com>
+M:	Heungjun Kim <riverful.kim@samsung.com>
+L:	linux-media@vger.kernel.org
+S:	Maintained
+F:	drivers/media/video/m5mols/
+F:	include/media/m5mols.h
+
 FUSE: FILESYSTEM IN USERSPACE
 M:	Miklos Szeredi <miklos@szeredi.hu>
 L:	fuse-devel@lists.sourceforge.net
diff --git a/drivers/media/common/tuners/mt2060.c b/drivers/media/common/tuners/mt2060.c
index 2d0e768..2ecaa53 100644
--- a/drivers/media/common/tuners/mt2060.c
+++ b/drivers/media/common/tuners/mt2060.c
@@ -300,6 +300,12 @@
 	return 0;
 }
 
+static int mt2060_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+	*frequency = IF2 * 1000;
+	return 0;
+}
+
 static int mt2060_init(struct dvb_frontend *fe)
 {
 	struct mt2060_priv *priv = fe->tuner_priv;
@@ -356,7 +362,8 @@
 
 	.set_params    = mt2060_set_params,
 	.get_frequency = mt2060_get_frequency,
-	.get_bandwidth = mt2060_get_bandwidth
+	.get_bandwidth = mt2060_get_bandwidth,
+	.get_if_frequency = mt2060_get_if_frequency,
 };
 
 /* This functions tries to identify a MT2060 tuner by reading the PART/REV register. This is hasty. */
diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c
index 5d02221..67bccde 100644
--- a/drivers/media/common/tuners/mxl5007t.c
+++ b/drivers/media/common/tuners/mxl5007t.c
@@ -165,6 +165,8 @@
 	struct reg_pair_t tab_init_cable[ARRAY_SIZE(init_tab_cable)];
 	struct reg_pair_t tab_rftune[ARRAY_SIZE(reg_pair_rftune)];
 
+	enum mxl5007t_if_freq if_freq;
+
 	u32 frequency;
 	u32 bandwidth;
 };
@@ -286,6 +288,8 @@
 	/* set inverted IF or normal IF */
 	set_reg_bits(state->tab_init, 0x02, 0x10, invert_if ? 0x10 : 0x00);
 
+	state->if_freq = if_freq;
+
 	return;
 }
 
@@ -738,6 +742,50 @@
 	return 0;
 }
 
+static int mxl5007t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+	struct mxl5007t_state *state = fe->tuner_priv;
+
+	*frequency = 0;
+
+	switch (state->if_freq) {
+	case MxL_IF_4_MHZ:
+		*frequency = 4000000;
+		break;
+	case MxL_IF_4_5_MHZ:
+		*frequency = 4500000;
+		break;
+	case MxL_IF_4_57_MHZ:
+		*frequency = 4570000;
+		break;
+	case MxL_IF_5_MHZ:
+		*frequency = 5000000;
+		break;
+	case MxL_IF_5_38_MHZ:
+		*frequency = 5380000;
+		break;
+	case MxL_IF_6_MHZ:
+		*frequency = 6000000;
+		break;
+	case MxL_IF_6_28_MHZ:
+		*frequency = 6280000;
+		break;
+	case MxL_IF_9_1915_MHZ:
+		*frequency = 9191500;
+		break;
+	case MxL_IF_35_25_MHZ:
+		*frequency = 35250000;
+		break;
+	case MxL_IF_36_15_MHZ:
+		*frequency = 36150000;
+		break;
+	case MxL_IF_44_MHZ:
+		*frequency = 44000000;
+		break;
+	}
+	return 0;
+}
+
 static int mxl5007t_release(struct dvb_frontend *fe)
 {
 	struct mxl5007t_state *state = fe->tuner_priv;
@@ -767,6 +815,7 @@
 	.get_frequency     = mxl5007t_get_frequency,
 	.get_bandwidth     = mxl5007t_get_bandwidth,
 	.release           = mxl5007t_release,
+	.get_if_frequency  = mxl5007t_get_if_frequency,
 };
 
 static int mxl5007t_get_chip_id(struct mxl5007t_state *state)
diff --git a/drivers/media/common/tuners/qt1010.c b/drivers/media/common/tuners/qt1010.c
index 9f5dba2..cd461c2 100644
--- a/drivers/media/common/tuners/qt1010.c
+++ b/drivers/media/common/tuners/qt1010.c
@@ -423,6 +423,12 @@
 	return 0;
 }
 
+static int qt1010_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+	*frequency = 36125000;
+	return 0;
+}
+
 static const struct dvb_tuner_ops qt1010_tuner_ops = {
 	.info = {
 		.name           = "Quantek QT1010",
@@ -437,7 +443,8 @@
 
 	.set_params    = qt1010_set_params,
 	.get_frequency = qt1010_get_frequency,
-	.get_bandwidth = qt1010_get_bandwidth
+	.get_bandwidth = qt1010_get_bandwidth,
+	.get_if_frequency = qt1010_get_if_frequency,
 };
 
 struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/common/tuners/tda18212.c b/drivers/media/common/tuners/tda18212.c
index e29cc2bc1..f52282e 100644
--- a/drivers/media/common/tuners/tda18212.c
+++ b/drivers/media/common/tuners/tda18212.c
@@ -25,6 +25,8 @@
 struct tda18212_priv {
 	struct tda18212_config *cfg;
 	struct i2c_adapter *i2c;
+
+	u32 if_frequency;
 };
 
 #define dbg(fmt, arg...)					\
@@ -136,12 +138,24 @@
 	int ret, i;
 	u32 if_khz;
 	u8 buf[9];
+	#define DVBT_6   0
+	#define DVBT_7   1
+	#define DVBT_8   2
+	#define DVBT2_6  3
+	#define DVBT2_7  4
+	#define DVBT2_8  5
+	#define DVBC_6   6
+	#define DVBC_8   7
 	static const u8 bw_params[][3] = {
-		/*  0f    13    23 */
-		{ 0xb3, 0x20, 0x03 }, /* DVB-T 6 MHz */
-		{ 0xb3, 0x31, 0x01 }, /* DVB-T 7 MHz */
-		{ 0xb3, 0x22, 0x01 }, /* DVB-T 8 MHz */
-		{ 0x92, 0x53, 0x03 }, /* DVB-C */
+		     /* reg:   0f    13    23 */
+		[DVBT_6]  = { 0xb3, 0x20, 0x03 },
+		[DVBT_7]  = { 0xb3, 0x31, 0x01 },
+		[DVBT_8]  = { 0xb3, 0x22, 0x01 },
+		[DVBT2_6] = { 0xbc, 0x20, 0x03 },
+		[DVBT2_7] = { 0xbc, 0x72, 0x03 },
+		[DVBT2_8] = { 0xbc, 0x22, 0x01 },
+		[DVBC_6]  = { 0x92, 0x50, 0x03 },
+		[DVBC_8]  = { 0x92, 0x53, 0x03 },
 	};
 
 	dbg("delsys=%d RF=%d BW=%d\n",
@@ -155,15 +169,34 @@
 		switch (c->bandwidth_hz) {
 		case 6000000:
 			if_khz = priv->cfg->if_dvbt_6;
-			i = 0;
+			i = DVBT_6;
 			break;
 		case 7000000:
 			if_khz = priv->cfg->if_dvbt_7;
-			i = 1;
+			i = DVBT_7;
 			break;
 		case 8000000:
 			if_khz = priv->cfg->if_dvbt_8;
-			i = 2;
+			i = DVBT_8;
+			break;
+		default:
+			ret = -EINVAL;
+			goto error;
+		}
+		break;
+	case SYS_DVBT2:
+		switch (c->bandwidth_hz) {
+		case 6000000:
+			if_khz = priv->cfg->if_dvbt2_6;
+			i = DVBT2_6;
+			break;
+		case 7000000:
+			if_khz = priv->cfg->if_dvbt2_7;
+			i = DVBT2_7;
+			break;
+		case 8000000:
+			if_khz = priv->cfg->if_dvbt2_8;
+			i = DVBT2_8;
 			break;
 		default:
 			ret = -EINVAL;
@@ -172,7 +205,7 @@
 		break;
 	case SYS_DVBC_ANNEX_AC:
 		if_khz = priv->cfg->if_dvbc;
-		i = 3;
+		i = DVBC_8;
 		break;
 	default:
 		ret = -EINVAL;
@@ -194,7 +227,7 @@
 	buf[0] = 0x02;
 	buf[1] = bw_params[i][1];
 	buf[2] = 0x03; /* default value */
-	buf[3] = if_khz / 50;
+	buf[3] = DIV_ROUND_CLOSEST(if_khz, 50);
 	buf[4] = ((c->frequency / 1000) >> 16) & 0xff;
 	buf[5] = ((c->frequency / 1000) >>  8) & 0xff;
 	buf[6] = ((c->frequency / 1000) >>  0) & 0xff;
@@ -204,6 +237,9 @@
 	if (ret)
 		goto error;
 
+	/* actual IF rounded as it is on register */
+	priv->if_frequency = buf[3] * 50 * 1000;
+
 exit:
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
@@ -215,6 +251,15 @@
 	goto exit;
 }
 
+static int tda18212_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+	struct tda18212_priv *priv = fe->tuner_priv;
+
+	*frequency = priv->if_frequency;
+
+	return 0;
+}
+
 static int tda18212_release(struct dvb_frontend *fe)
 {
 	kfree(fe->tuner_priv);
@@ -234,6 +279,7 @@
 	.release       = tda18212_release,
 
 	.set_params    = tda18212_set_params,
+	.get_if_frequency = tda18212_get_if_frequency,
 };
 
 struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/common/tuners/tda18212.h b/drivers/media/common/tuners/tda18212.h
index 83b497f..9bd5da4 100644
--- a/drivers/media/common/tuners/tda18212.h
+++ b/drivers/media/common/tuners/tda18212.h
@@ -29,6 +29,10 @@
 	u16 if_dvbt_6;
 	u16 if_dvbt_7;
 	u16 if_dvbt_8;
+	u16 if_dvbt2_5;
+	u16 if_dvbt2_6;
+	u16 if_dvbt2_7;
+	u16 if_dvbt2_8;
 	u16 if_dvbc;
 };
 
diff --git a/drivers/media/common/tuners/tda18218.c b/drivers/media/common/tuners/tda18218.c
index 4fc2973..d099501 100644
--- a/drivers/media/common/tuners/tda18218.c
+++ b/drivers/media/common/tuners/tda18218.c
@@ -141,19 +141,21 @@
 	switch (params->u.ofdm.bandwidth) {
 	case BANDWIDTH_6_MHZ:
 		LP_Fc = 0;
-		LO_Frac = params->frequency + 3000000;
+		priv->if_frequency = 3000000;
 		break;
 	case BANDWIDTH_7_MHZ:
 		LP_Fc = 1;
-		LO_Frac = params->frequency + 3500000;
+		priv->if_frequency = 3500000;
 		break;
 	case BANDWIDTH_8_MHZ:
 	default:
 		LP_Fc = 2;
-		LO_Frac = params->frequency + 4000000;
+		priv->if_frequency = 4000000;
 		break;
 	}
 
+	LO_Frac = params->frequency + priv->if_frequency;
+
 	/* band-pass filter */
 	if (LO_Frac < 188000000)
 		BP_Filter = 3;
@@ -206,6 +208,14 @@
 	return ret;
 }
 
+static int tda18218_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+	struct tda18218_priv *priv = fe->tuner_priv;
+	*frequency = priv->if_frequency;
+	dbg("%s: if=%d", __func__, *frequency);
+	return 0;
+}
+
 static int tda18218_sleep(struct dvb_frontend *fe)
 {
 	struct tda18218_priv *priv = fe->tuner_priv;
@@ -268,6 +278,8 @@
 	.sleep         = tda18218_sleep,
 
 	.set_params    = tda18218_set_params,
+
+	.get_if_frequency = tda18218_get_if_frequency,
 };
 
 struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/common/tuners/tda18218_priv.h b/drivers/media/common/tuners/tda18218_priv.h
index 904e536..dc52b72 100644
--- a/drivers/media/common/tuners/tda18218_priv.h
+++ b/drivers/media/common/tuners/tda18218_priv.h
@@ -100,6 +100,8 @@
 	struct tda18218_config *cfg;
 	struct i2c_adapter *i2c;
 
+	u32 if_frequency;
+
 	u8 regs[TDA18218_NUM_REGS];
 };
 
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
index 63cc400..3347c5b 100644
--- a/drivers/media/common/tuners/tda18271-fe.c
+++ b/drivers/media/common/tuners/tda18271-fe.c
@@ -994,6 +994,7 @@
 	if (tda_fail(ret))
 		goto fail;
 
+	priv->if_freq   = map->if_freq;
 	priv->frequency = freq;
 	priv->bandwidth = (fe->ops.info.type == FE_OFDM) ?
 		params->u.ofdm.bandwidth : 0;
@@ -1050,6 +1051,7 @@
 	if (tda_fail(ret))
 		goto fail;
 
+	priv->if_freq   = map->if_freq;
 	priv->frequency = freq;
 	priv->bandwidth = 0;
 fail:
@@ -1086,6 +1088,13 @@
 	return 0;
 }
 
+static int tda18271_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+	struct tda18271_priv *priv = fe->tuner_priv;
+	*frequency = (u32)priv->if_freq * 1000;
+	return 0;
+}
+
 /* ------------------------------------------------------------------ */
 
 #define tda18271_update_std(std_cfg, name) do {				\
@@ -1245,6 +1254,7 @@
 	.set_config        = tda18271_set_config,
 	.get_frequency     = tda18271_get_frequency,
 	.get_bandwidth     = tda18271_get_bandwidth,
+	.get_if_frequency  = tda18271_get_if_frequency,
 };
 
 struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h
index 94340f4..454c152 100644
--- a/drivers/media/common/tuners/tda18271-priv.h
+++ b/drivers/media/common/tuners/tda18271-priv.h
@@ -122,6 +122,8 @@
 
 	struct mutex lock;
 
+	u16 if_freq;
+
 	u32 frequency;
 	u32 bandwidth;
 };
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c
index f8ee29e..4092200 100644
--- a/drivers/media/common/tuners/tuner-simple.c
+++ b/drivers/media/common/tuners/tuner-simple.c
@@ -751,6 +751,17 @@
 	if (4 != rc)
 		tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc);
 
+	/* Write AUX byte */
+	switch (priv->type) {
+	case TUNER_PHILIPS_FM1216ME_MK3:
+		buffer[2] = 0x98;
+		buffer[3] = 0x20; /* set TOP AGC */
+		rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4);
+		if (4 != rc)
+			tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc);
+		break;
+	}
+
 	return 0;
 }
 
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
index 3acbaa0..e531267 100644
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -891,7 +891,7 @@
 
 	/* Frequency is locked */
 	if (frq_lock == 1)
-		signal = 32768;
+		signal = 1 << 11;
 
 	/* Get SNR of the video signal */
 	rc = xc2028_get_reg(priv, 0x0040, &signal);
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index aa1b2e8..5c56d3c 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -628,20 +628,14 @@
 	dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
 }
 
-/*
- * As defined on EN 300 429, the DVB-C roll-off factor is 0.15.
- * So, the amount of the needed bandwith is given by:
- * 	Bw = Symbol_rate * (1 + 0.15)
- * As such, the maximum symbol rate supported by 6 MHz is given by:
- *	max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds
- */
-#define MAX_SYMBOL_RATE_6MHz	5217391
-
 static int xc5000_set_params(struct dvb_frontend *fe,
-	struct dvb_frontend_parameters *params)
+			     struct dvb_frontend_parameters *params)
 {
+	int ret, b;
 	struct xc5000_priv *priv = fe->tuner_priv;
-	int ret;
+	u32 bw = fe->dtv_property_cache.bandwidth_hz;
+	u32 freq = fe->dtv_property_cache.frequency;
+	u32 delsys  = fe->dtv_property_cache.delivery_system;
 
 	if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
 		if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
@@ -650,88 +644,77 @@
 		}
 	}
 
-	dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
+	dprintk(1, "%s() frequency=%d (Hz)\n", __func__, freq);
 
-	if (fe->ops.info.type == FE_ATSC) {
-		dprintk(1, "%s() ATSC\n", __func__);
-		switch (params->u.vsb.modulation) {
-		case VSB_8:
-		case VSB_16:
-			dprintk(1, "%s() VSB modulation\n", __func__);
-			priv->rf_mode = XC_RF_MODE_AIR;
-			priv->freq_hz = params->frequency - 1750000;
-			priv->bandwidth = BANDWIDTH_6_MHZ;
-			priv->video_standard = DTV6;
-			break;
-		case QAM_64:
-		case QAM_256:
-		case QAM_AUTO:
-			dprintk(1, "%s() QAM modulation\n", __func__);
-			priv->rf_mode = XC_RF_MODE_CABLE;
-			priv->freq_hz = params->frequency - 1750000;
-			priv->bandwidth = BANDWIDTH_6_MHZ;
-			priv->video_standard = DTV6;
-			break;
-		default:
-			return -EINVAL;
-		}
-	} else if (fe->ops.info.type == FE_OFDM) {
+	switch (delsys) {
+	case SYS_ATSC:
+		dprintk(1, "%s() VSB modulation\n", __func__);
+		priv->rf_mode = XC_RF_MODE_AIR;
+		priv->freq_hz = freq - 1750000;
+		priv->bandwidth = BANDWIDTH_6_MHZ;
+		priv->video_standard = DTV6;
+		break;
+	case SYS_DVBC_ANNEX_B:
+		dprintk(1, "%s() QAM modulation\n", __func__);
+		priv->rf_mode = XC_RF_MODE_CABLE;
+		priv->freq_hz = freq - 1750000;
+		priv->bandwidth = BANDWIDTH_6_MHZ;
+		priv->video_standard = DTV6;
+		break;
+	case SYS_DVBT:
+	case SYS_DVBT2:
 		dprintk(1, "%s() OFDM\n", __func__);
-		switch (params->u.ofdm.bandwidth) {
-		case BANDWIDTH_6_MHZ:
+		switch (bw) {
+		case 6000000:
 			priv->bandwidth = BANDWIDTH_6_MHZ;
 			priv->video_standard = DTV6;
-			priv->freq_hz = params->frequency - 1750000;
+			priv->freq_hz = freq - 1750000;
 			break;
-		case BANDWIDTH_7_MHZ:
-			printk(KERN_ERR "xc5000 bandwidth 7MHz not supported\n");
-			return -EINVAL;
-		case BANDWIDTH_8_MHZ:
+		case 7000000:
+			priv->bandwidth = BANDWIDTH_7_MHZ;
+			priv->video_standard = DTV7;
+			priv->freq_hz = freq - 2250000;
+			break;
+		case 8000000:
 			priv->bandwidth = BANDWIDTH_8_MHZ;
 			priv->video_standard = DTV8;
-			priv->freq_hz = params->frequency - 2750000;
+			priv->freq_hz = freq - 2750000;
 			break;
 		default:
 			printk(KERN_ERR "xc5000 bandwidth not set!\n");
 			return -EINVAL;
 		}
 		priv->rf_mode = XC_RF_MODE_AIR;
-	} else if (fe->ops.info.type == FE_QAM) {
-		switch (params->u.qam.modulation) {
-		case QAM_256:
-		case QAM_AUTO:
-		case QAM_16:
-		case QAM_32:
-		case QAM_64:
-		case QAM_128:
-			dprintk(1, "%s() QAM modulation\n", __func__);
-			priv->rf_mode = XC_RF_MODE_CABLE;
-			/*
-			 * Using a 8MHz bandwidth sometimes fail
-			 * with 6MHz-spaced channels, due to inter-carrier
-			 * interference. So, use DTV6 firmware
-			 */
-			if (params->u.qam.symbol_rate <= MAX_SYMBOL_RATE_6MHz) {
-				priv->bandwidth = BANDWIDTH_6_MHZ;
-				priv->video_standard = DTV6;
-				priv->freq_hz = params->frequency - 1750000;
-			} else {
-				priv->bandwidth = BANDWIDTH_8_MHZ;
-				priv->video_standard = DTV7_8;
-				priv->freq_hz = params->frequency - 2750000;
-			}
-			break;
-		default:
-			dprintk(1, "%s() Unsupported QAM type\n", __func__);
-			return -EINVAL;
+	case SYS_DVBC_ANNEX_A:
+	case SYS_DVBC_ANNEX_C:
+		dprintk(1, "%s() QAM modulation\n", __func__);
+		priv->rf_mode = XC_RF_MODE_CABLE;
+		if (bw <= 6000000) {
+			priv->bandwidth = BANDWIDTH_6_MHZ;
+			priv->video_standard = DTV6;
+			priv->freq_hz = freq - 1750000;
+			b = 6;
+		} else if (bw <= 7000000) {
+			priv->bandwidth = BANDWIDTH_7_MHZ;
+			priv->video_standard = DTV7;
+			priv->freq_hz = freq - 2250000;
+			b = 7;
+		} else {
+			priv->bandwidth = BANDWIDTH_8_MHZ;
+			priv->video_standard = DTV7_8;
+			priv->freq_hz = freq - 2750000;
+			b = 8;
 		}
-	} else {
-		printk(KERN_ERR "xc5000 modulation type not supported!\n");
+		dprintk(1, "%s() Bandwidth %dMHz (%d)\n", __func__,
+			b, bw);
+		break;
+	default:
+		printk(KERN_ERR "xc5000: delivery system is not supported!\n");
 		return -EINVAL;
 	}
 
-	dprintk(1, "%s() frequency=%d (compensated)\n",
-		__func__, priv->freq_hz);
+	dprintk(1, "%s() frequency=%d (compensated to %d)\n",
+		__func__, freq, priv->freq_hz);
 
 	ret = xc_SetSignalSource(priv, priv->rf_mode);
 	if (ret != XC_RESULT_SUCCESS) {
@@ -968,6 +951,14 @@
 	return 0;
 }
 
+static int xc5000_get_if_frequency(struct dvb_frontend *fe, u32 *freq)
+{
+	struct xc5000_priv *priv = fe->tuner_priv;
+	dprintk(1, "%s()\n", __func__);
+	*freq = priv->if_khz * 1000;
+	return 0;
+}
+
 static int xc5000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
 {
 	struct xc5000_priv *priv = fe->tuner_priv;
@@ -1108,6 +1099,7 @@
 	.set_params	   = xc5000_set_params,
 	.set_analog_params = xc5000_set_analog_params,
 	.get_frequency	   = xc5000_get_frequency,
+	.get_if_frequency  = xc5000_get_if_frequency,
 	.get_bandwidth	   = xc5000_get_bandwidth,
 	.get_status	   = xc5000_get_status
 };
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 2c0acdb..66537b1 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -876,6 +876,7 @@
 	c->symbol_rate = QAM_AUTO;
 	c->code_rate_HP = FEC_AUTO;
 	c->code_rate_LP = FEC_AUTO;
+	c->rolloff = ROLLOFF_AUTO;
 
 	c->isdbt_partial_reception = -1;
 	c->isdbt_sb_mode = -1;
@@ -973,6 +974,8 @@
 	_DTV_CMD(DTV_GUARD_INTERVAL, 0, 0),
 	_DTV_CMD(DTV_TRANSMISSION_MODE, 0, 0),
 	_DTV_CMD(DTV_HIERARCHY, 0, 0),
+
+	_DTV_CMD(DTV_ENUM_DELSYS, 0, 0),
 };
 
 static void dtv_property_dump(struct dtv_property *tvp)
@@ -1008,7 +1011,7 @@
 
 static int is_legacy_delivery_system(fe_delivery_system_t s)
 {
-	if((s == SYS_UNDEFINED) || (s == SYS_DVBC_ANNEX_AC) ||
+	if((s == SYS_UNDEFINED) || (s == SYS_DVBC_ANNEX_A) ||
 	   (s == SYS_DVBC_ANNEX_B) || (s == SYS_DVBT) || (s == SYS_DVBS) ||
 	   (s == SYS_ATSC))
 		return 1;
@@ -1029,7 +1032,7 @@
 		c->delivery_system = SYS_DVBS;
 		break;
 	case FE_QAM:
-		c->delivery_system = SYS_DVBC_ANNEX_AC;
+		c->delivery_system = SYS_DVBC_ANNEX_A;
 		break;
 	case FE_OFDM:
 		c->delivery_system = SYS_DVBT;
@@ -1140,9 +1143,10 @@
  */
 static void dtv_property_adv_params_sync(struct dvb_frontend *fe)
 {
-	const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	struct dvb_frontend_parameters *p = &fepriv->parameters_in;
+	u32 rolloff = 0;
 
 	p->frequency = c->frequency;
 	p->inversion = c->inversion;
@@ -1174,6 +1178,23 @@
 		else
 			p->u.ofdm.bandwidth = BANDWIDTH_AUTO;
 	}
+
+	/*
+	 * On DVB-C, the bandwidth is a function of roll-off and symbol rate.
+	 * The bandwidth is required for DVB-C tuners, in order to avoid
+	 * inter-channel noise. Instead of estimating the minimal required
+	 * bandwidth on every single driver, calculates it here and fills
+	 * it at the cache bandwidth parameter.
+	 * While not officially supported, a side effect of handling it at
+	 * the cache level is that a program could retrieve the bandwidth
+	 * via DTV_BANDWIDTH_HZ, wich may be useful for test programs.
+	 */
+	if (c->delivery_system == SYS_DVBC_ANNEX_A)
+		rolloff = 115;
+	if (c->delivery_system == SYS_DVBC_ANNEX_C)
+		rolloff = 113;
+	if (rolloff)
+		c->bandwidth_hz = (c->symbol_rate * rolloff) / 100;
 }
 
 static void dtv_property_cache_submit(struct dvb_frontend *fe)
@@ -1207,6 +1228,37 @@
 static int dvb_frontend_ioctl_properties(struct file *file,
 			unsigned int cmd, void *parg);
 
+static void dtv_set_default_delivery_caps(const struct dvb_frontend *fe, struct dtv_property *p)
+{
+	const struct dvb_frontend_info *info = &fe->ops.info;
+	u32 ncaps = 0;
+
+	switch (info->type) {
+	case FE_QPSK:
+		p->u.buffer.data[ncaps++] = SYS_DVBS;
+		if (info->caps & FE_CAN_2G_MODULATION)
+			p->u.buffer.data[ncaps++] = SYS_DVBS2;
+		if (info->caps & FE_CAN_TURBO_FEC)
+			p->u.buffer.data[ncaps++] = SYS_TURBO;
+		break;
+	case FE_QAM:
+		p->u.buffer.data[ncaps++] = SYS_DVBC_ANNEX_AC;
+		break;
+	case FE_OFDM:
+		p->u.buffer.data[ncaps++] = SYS_DVBT;
+		if (info->caps & FE_CAN_2G_MODULATION)
+			p->u.buffer.data[ncaps++] = SYS_DVBT2;
+		break;
+	case FE_ATSC:
+		if (info->caps & (FE_CAN_8VSB | FE_CAN_16VSB))
+			p->u.buffer.data[ncaps++] = SYS_ATSC;
+		if (info->caps & (FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256))
+			p->u.buffer.data[ncaps++] = SYS_DVBC_ANNEX_B;
+		break;
+	}
+	p->u.buffer.len = ncaps;
+}
+
 static int dtv_property_process_get(struct dvb_frontend *fe,
 				    struct dtv_property *tvp,
 				    struct file *file)
@@ -1227,6 +1279,9 @@
 	}
 
 	switch(tvp->cmd) {
+	case DTV_ENUM_DELSYS:
+		dtv_set_default_delivery_caps(fe, tvp);
+		break;
 	case DTV_FREQUENCY:
 		tvp->u.data = c->frequency;
 		break;
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 5825716..9f203c6 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -311,6 +311,7 @@
 	select DVB_STV0900 if !DVB_FE_CUSTOMISE
 	select DVB_STV6110 if !DVB_FE_CUSTOMISE
 	select DVB_ISL6423 if !DVB_FE_CUSTOMISE
+	select DVB_CXD2820R if !DVB_FE_CUSTOMISE
 	help
 	  Say Y here to support the Anysee E30, Anysee E30 Plus or
 	  Anysee E30 C Plus DVB USB2.0 receiver.
@@ -340,7 +341,7 @@
 
 config DVB_USB_CE6230
 	tristate "Intel CE6230 DVB-T USB2.0 support"
-	depends on DVB_USB && EXPERIMENTAL
+	depends on DVB_USB
 	select DVB_ZL10353
 	select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
 	help
@@ -354,7 +355,7 @@
 
 config DVB_USB_EC168
 	tristate "E3C EC168 DVB-T USB2.0 support"
-	depends on DVB_USB && EXPERIMENTAL
+	depends on DVB_USB
 	select DVB_EC100
 	select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
 	help
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index 5f2278b..df46015 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -41,6 +41,7 @@
 #include "stv0900.h"
 #include "stv6110.h"
 #include "isl6423.h"
+#include "cxd2820r.h"
 
 /* debug */
 static int dvb_usb_anysee_debug;
@@ -66,10 +67,12 @@
 	if (mutex_lock_interruptible(&anysee_usb_mutex) < 0)
 		return -EAGAIN;
 
+	deb_xfer(">>> ");
+	debug_dump(buf, slen, deb_xfer);
+
 	/* We need receive one message more after dvb_usb_generic_rw due
 	   to weird transaction flow, which is 1 x send + 2 x receive. */
 	ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0);
-
 	if (!ret) {
 		/* receive 2nd answer */
 		ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
@@ -79,7 +82,10 @@
 			err("%s: recv bulk message failed: %d", __func__, ret);
 		else {
 			deb_xfer("<<< ");
-			debug_dump(buf, act_len, deb_xfer);
+			debug_dump(buf, rlen, deb_xfer);
+
+			if (buf[63] != 0x4f)
+				deb_info("%s: cmd failed\n", __func__);
 		}
 	}
 
@@ -129,6 +135,29 @@
 	return anysee_write_reg(d, reg, val);
 }
 
+/* read single register with mask */
+static int anysee_rd_reg_mask(struct dvb_usb_device *d, u16 reg, u8 *val,
+	u8 mask)
+{
+	int ret, i;
+	u8 tmp;
+
+	ret = anysee_read_reg(d, reg, &tmp);
+	if (ret)
+		return ret;
+
+	tmp &= mask;
+
+	/* find position of the first bit */
+	for (i = 0; i < 8; i++) {
+		if ((mask >> i) & 0x01)
+			break;
+	}
+	*val = tmp >> i;
+
+	return 0;
+}
+
 static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
 {
 	u8 buf[] = {CMD_GET_HW_INFO};
@@ -156,22 +185,6 @@
 	return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
 }
 
-static int anysee_init(struct dvb_usb_device *d)
-{
-	int ret;
-	/* LED light */
-	ret = anysee_led_ctrl(d, 0x01, 0x03);
-	if (ret)
-		return ret;
-
-	/* enable IR */
-	ret = anysee_ir_ctrl(d, 1);
-	if (ret)
-		return ret;
-
-	return 0;
-}
-
 /* I2C */
 static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
 	int num)
@@ -297,7 +310,7 @@
 	.pll_m  = 12,
 	.pll_p  = 3,
 	.pll_n  = 1,
-	.output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
+	.output_mode = TDA10023_OUTPUT_MODE_PARALLEL_B,
 	.deltaf = 0xba02,
 };
 
@@ -309,6 +322,17 @@
 	.if_dvbc = 5000,
 };
 
+static struct tda18212_config anysee_tda18212_config2 = {
+	.i2c_address = 0x60 /* (0xc0 >> 1) */,
+	.if_dvbt_6 = 3550,
+	.if_dvbt_7 = 3700,
+	.if_dvbt_8 = 4150,
+	.if_dvbt2_6 = 3250,
+	.if_dvbt2_7 = 4000,
+	.if_dvbt2_8 = 4000,
+	.if_dvbc = 5000,
+};
+
 static struct cx24116_config anysee_cx24116_config = {
 	.demod_address = (0xaa >> 1),
 	.mpg_clk_pos_pol = 0x00,
@@ -339,6 +363,11 @@
 	.addr = (0x10 >> 1),
 };
 
+static struct cxd2820r_config anysee_cxd2820r_config = {
+	.i2c_address = 0x6d, /* (0xda >> 1) */
+	.ts_mode = 0x38,
+};
+
 /*
  * New USB device strings: Mfr=1, Product=2, SerialNumber=0
  * Manufacturer: AMT.CO.KR
@@ -421,6 +450,14 @@
  * IOA[7] TS 1=enabled
  * IOE[5] STV0903 1=enabled
  *
+ * E7 T2C VID=1c73 PID=861f HW=20 FW=0.1 AMTCI=0.5 "anysee-E7T2C(LP)"
+ * PCB: 508T2C (rev0.3)
+ * parts: DNOQ44QCH106A(CXD2820R, TDA18212), TDA8024
+ * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
+ * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
+ * IOA[7] TS 1=enabled
+ * IOE[5] CXD2820R 1=enabled
+ *
  * E7 PTC VID=1c73 PID=861f HW=21 FW=0.1 AMTCI=?? "anysee-E7PTC(LP)"
  * PCB: 508PTC (rev0.5)
  * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
@@ -437,7 +474,7 @@
  * IOD[6] ZL10353 1=enabled
  * IOE[0] IF 0=enabled
  *
- * E7 S2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)"
+ * E7 PS2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)"
  * PCB: 508PS2 (rev0.4)
  * parts: DNBU10512IST(STV0903, STV6110), ISL6423
  * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
@@ -446,6 +483,16 @@
  * IOE[5] STV0903 1=enabled
  */
 
+
+/* external I2C gate used for DNOD44CDH086A(TDA18212) tuner module */
+static int anysee_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
+
+	/* enable / disable tuner access on IOE[4] */
+	return anysee_wr_reg_mask(adap->dev, REG_IOE, (enable << 4), 0x10);
+}
+
 static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff)
 {
 	struct dvb_usb_adapter *adap = fe->dvb->priv;
@@ -577,7 +624,8 @@
 	/* detect hardware only once */
 	if (adap->fe_adap[0].fe == NULL) {
 		/* Check which hardware we have.
-		 * We must do this call two times to get reliable values (hw bug).
+		 * We must do this call two times to get reliable values
+		 * (hw/fw bug).
 		 */
 		ret = anysee_get_hw_info(adap->dev, hw_info);
 		if (ret)
@@ -606,14 +654,14 @@
 			break;
 
 		/* attach demod */
-		adap->fe_adap[0].fe = dvb_attach(mt352_attach, &anysee_mt352_config,
-			&adap->dev->i2c_adap);
+		adap->fe_adap[0].fe = dvb_attach(mt352_attach,
+			&anysee_mt352_config, &adap->dev->i2c_adap);
 		if (adap->fe_adap[0].fe)
 			break;
 
 		/* attach demod */
-		adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
-			&adap->dev->i2c_adap);
+		adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
+			&anysee_zl10353_config, &adap->dev->i2c_adap);
 
 		break;
 	case ANYSEE_HW_507CD: /* 6 */
@@ -665,8 +713,8 @@
 			goto error;
 
 		/* attach demod */
-		adap->fe_adap[0].fe = dvb_attach(cx24116_attach, &anysee_cx24116_config,
-			&adap->dev->i2c_adap);
+		adap->fe_adap[0].fe = dvb_attach(cx24116_attach,
+			&anysee_cx24116_config, &adap->dev->i2c_adap);
 
 		break;
 	case ANYSEE_HW_507FA: /* 15 */
@@ -747,17 +795,19 @@
 			}
 		}
 
+		/* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
+		if (tmp == 0xc7) {
+			if (adap->fe_adap[state->fe_id].fe)
+				adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl =
+					anysee_i2c_gate_ctrl;
+		}
+
 		break;
 	case ANYSEE_HW_508TC: /* 18 */
 	case ANYSEE_HW_508PTC: /* 21 */
 		/* E7 TC */
 		/* E7 PTC */
 
-		/* enable transport stream on IOA[7] */
-		ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80);
-		if (ret)
-			goto error;
-
 		if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0)  {
 			/* disable DVB-T demod on IOD[6] */
 			ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6),
@@ -772,7 +822,8 @@
 				goto error;
 
 			/* attach demod */
-			adap->fe_adap[state->fe_id].fe = dvb_attach(tda10023_attach,
+			adap->fe_adap[state->fe_id].fe =
+				dvb_attach(tda10023_attach,
 				&anysee_tda10023_tda18212_config,
 				&adap->dev->i2c_adap, 0x48);
 		} else {
@@ -789,11 +840,19 @@
 				goto error;
 
 			/* attach demod */
-			adap->fe_adap[state->fe_id].fe = dvb_attach(zl10353_attach,
+			adap->fe_adap[state->fe_id].fe =
+				dvb_attach(zl10353_attach,
 				&anysee_zl10353_tda18212_config,
 				&adap->dev->i2c_adap);
 		}
 
+		/* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
+		if (adap->fe_adap[state->fe_id].fe)
+			adap->fe_adap[state->fe_id].fe->ops.i2c_gate_ctrl =
+				anysee_i2c_gate_ctrl;
+
+		state->has_ci = true;
+
 		break;
 	case ANYSEE_HW_508S2: /* 19 */
 	case ANYSEE_HW_508PS2: /* 22 */
@@ -803,19 +862,41 @@
 		if (state->fe_id)
 			break;
 
-		/* enable transport stream on IOA[7] */
-		ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80);
-		if (ret)
-			goto error;
-
 		/* enable DVB-S/S2 demod on IOE[5] */
 		ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20);
 		if (ret)
 			goto error;
 
 		/* attach demod */
-		adap->fe_adap[0].fe = dvb_attach(stv0900_attach, &anysee_stv0900_config,
-			&adap->dev->i2c_adap, 0);
+		adap->fe_adap[0].fe = dvb_attach(stv0900_attach,
+			&anysee_stv0900_config, &adap->dev->i2c_adap, 0);
+
+		state->has_ci = true;
+
+		break;
+	case ANYSEE_HW_508T2C: /* 20 */
+		/* E7 T2C */
+
+		/* enable DVB-T/T2/C demod on IOE[5] */
+		ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20);
+		if (ret)
+			goto error;
+
+		if (state->fe_id == 0)  {
+			/* DVB-T/T2 */
+			adap->fe_adap[state->fe_id].fe =
+				dvb_attach(cxd2820r_attach,
+				&anysee_cxd2820r_config,
+				&adap->dev->i2c_adap, NULL);
+		} else {
+			/* DVB-C */
+			adap->fe_adap[state->fe_id].fe =
+				dvb_attach(cxd2820r_attach,
+				&anysee_cxd2820r_config,
+				&adap->dev->i2c_adap, adap->fe_adap[0].fe);
+		}
+
+		state->has_ci = true;
 
 		break;
 	}
@@ -842,24 +923,26 @@
 		/* E30 */
 
 		/* attach tuner */
-		fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc2 >> 1),
-			NULL, DVB_PLL_THOMSON_DTT7579);
+		fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe,
+			(0xc2 >> 1), NULL, DVB_PLL_THOMSON_DTT7579);
 
 		break;
 	case ANYSEE_HW_507CD: /* 6 */
 		/* E30 Plus */
 
 		/* attach tuner */
-		fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc2 >> 1),
-			&adap->dev->i2c_adap, DVB_PLL_THOMSON_DTT7579);
+		fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe,
+			(0xc2 >> 1), &adap->dev->i2c_adap,
+			DVB_PLL_THOMSON_DTT7579);
 
 		break;
 	case ANYSEE_HW_507DC: /* 10 */
 		/* E30 C Plus */
 
 		/* attach tuner */
-		fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc0 >> 1),
-			&adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
+		fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe,
+			(0xc0 >> 1), &adap->dev->i2c_adap,
+			DVB_PLL_SAMSUNG_DTOS403IH102A);
 
 		break;
 	case ANYSEE_HW_507SI: /* 11 */
@@ -877,22 +960,12 @@
 		/* Try first attach TDA18212 silicon tuner on IOE[4], if that
 		 * fails attach old simple PLL. */
 
-		/* enable tuner on IOE[4] */
-		ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
-		if (ret)
-			goto error;
-
 		/* attach tuner */
 		fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe,
 			&adap->dev->i2c_adap, &anysee_tda18212_config);
 		if (fe)
 			break;
 
-		/* disable tuner on IOE[4] */
-		ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10);
-		if (ret)
-			goto error;
-
 		/* attach tuner */
 		fe = dvb_attach(dvb_pll_attach, adap->fe_adap[state->fe_id].fe,
 			(0xc0 >> 1), &adap->dev->i2c_adap,
@@ -904,11 +977,6 @@
 		/* E7 TC */
 		/* E7 PTC */
 
-		/* enable tuner on IOE[4] */
-		ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
-		if (ret)
-			goto error;
-
 		/* attach tuner */
 		fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe,
 			&adap->dev->i2c_adap, &anysee_tda18212_config);
@@ -930,6 +998,15 @@
 		}
 
 		break;
+
+	case ANYSEE_HW_508T2C: /* 20 */
+		/* E7 T2C */
+
+		/* attach tuner */
+		fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe,
+			&adap->dev->i2c_adap, &anysee_tda18212_config2);
+
+		break;
 	default:
 		fe = NULL;
 	}
@@ -939,7 +1016,6 @@
 	else
 		ret = -ENODEV;
 
-error:
 	return ret;
 }
 
@@ -969,6 +1045,201 @@
 	return 0;
 }
 
+static int anysee_ci_read_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
+	int addr)
+{
+	struct dvb_usb_device *d = ci->data;
+	int ret;
+	u8 buf[] = {CMD_CI, 0x02, 0x40 | addr >> 8, addr & 0xff, 0x00, 1};
+	u8 val;
+
+	ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
+	if (ret)
+		return ret;
+
+	return val;
+}
+
+static int anysee_ci_write_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
+	int addr, u8 val)
+{
+	struct dvb_usb_device *d = ci->data;
+	int ret;
+	u8 buf[] = {CMD_CI, 0x03, 0x40 | addr >> 8, addr & 0xff, 0x00, 1, val};
+
+	ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int anysee_ci_read_cam_control(struct dvb_ca_en50221 *ci, int slot,
+	u8 addr)
+{
+	struct dvb_usb_device *d = ci->data;
+	int ret;
+	u8 buf[] = {CMD_CI, 0x04, 0x40, addr, 0x00, 1};
+	u8 val;
+
+	ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
+	if (ret)
+		return ret;
+
+	return val;
+}
+
+static int anysee_ci_write_cam_control(struct dvb_ca_en50221 *ci, int slot,
+	u8 addr, u8 val)
+{
+	struct dvb_usb_device *d = ci->data;
+	int ret;
+	u8 buf[] = {CMD_CI, 0x05, 0x40, addr, 0x00, 1, val};
+
+	ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int anysee_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot)
+{
+	struct dvb_usb_device *d = ci->data;
+	int ret;
+	struct anysee_state *state = d->priv;
+
+	state->ci_cam_ready = jiffies + msecs_to_jiffies(1000);
+
+	ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
+	if (ret)
+		return ret;
+
+	msleep(300);
+
+	ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int anysee_ci_slot_shutdown(struct dvb_ca_en50221 *ci, int slot)
+{
+	struct dvb_usb_device *d = ci->data;
+	int ret;
+
+	ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
+	if (ret)
+		return ret;
+
+	msleep(30);
+
+	ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int anysee_ci_slot_ts_enable(struct dvb_ca_en50221 *ci, int slot)
+{
+	struct dvb_usb_device *d = ci->data;
+	int ret;
+
+	ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 1), 0x02);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot,
+	int open)
+{
+	struct dvb_usb_device *d = ci->data;
+	struct anysee_state *state = d->priv;
+	int ret;
+	u8 tmp;
+
+	ret = anysee_rd_reg_mask(d, REG_IOC, &tmp, 0x40);
+	if (ret)
+		return ret;
+
+	if (tmp == 0) {
+		ret = DVB_CA_EN50221_POLL_CAM_PRESENT;
+		if (time_after(jiffies, state->ci_cam_ready))
+			ret |= DVB_CA_EN50221_POLL_CAM_READY;
+	}
+
+	return ret;
+}
+
+static int anysee_ci_init(struct dvb_usb_device *d)
+{
+	struct anysee_state *state = d->priv;
+	int ret;
+
+	state->ci.owner               = THIS_MODULE;
+	state->ci.read_attribute_mem  = anysee_ci_read_attribute_mem;
+	state->ci.write_attribute_mem = anysee_ci_write_attribute_mem;
+	state->ci.read_cam_control    = anysee_ci_read_cam_control;
+	state->ci.write_cam_control   = anysee_ci_write_cam_control;
+	state->ci.slot_reset          = anysee_ci_slot_reset;
+	state->ci.slot_shutdown       = anysee_ci_slot_shutdown;
+	state->ci.slot_ts_enable      = anysee_ci_slot_ts_enable;
+	state->ci.poll_slot_status    = anysee_ci_poll_slot_status;
+	state->ci.data                = d;
+
+	ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
+	if (ret)
+		return ret;
+
+	ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void anysee_ci_release(struct dvb_usb_device *d)
+{
+	struct anysee_state *state = d->priv;
+
+	/* detach CI */
+	if (state->has_ci)
+		dvb_ca_en50221_release(&state->ci);
+
+	return;
+}
+
+static int anysee_init(struct dvb_usb_device *d)
+{
+	struct anysee_state *state = d->priv;
+	int ret;
+
+	/* LED light */
+	ret = anysee_led_ctrl(d, 0x01, 0x03);
+	if (ret)
+		return ret;
+
+	/* enable IR */
+	ret = anysee_ir_ctrl(d, 1);
+	if (ret)
+		return ret;
+
+	/* attach CI */
+	if (state->has_ci) {
+		ret = anysee_ci_init(d);
+		if (ret) {
+			state->has_ci = false;
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
 /* DVB USB Driver stuff */
 static struct dvb_usb_device_properties anysee_properties;
 
@@ -1010,6 +1281,16 @@
 	return anysee_init(d);
 }
 
+static void anysee_disconnect(struct usb_interface *intf)
+{
+	struct dvb_usb_device *d = usb_get_intfdata(intf);
+
+	anysee_ci_release(d);
+	dvb_usb_device_exit(intf);
+
+	return;
+}
+
 static struct usb_device_id anysee_table[] = {
 	{ USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) },
 	{ USB_DEVICE(USB_VID_AMT,     USB_PID_ANYSEE) },
@@ -1029,7 +1310,7 @@
 		{
 		.num_frontends    = 2,
 		.frontend_ctrl    = anysee_frontend_ctrl,
-		.fe = {{
+		.fe = { {
 			.streaming_ctrl   = anysee_streaming_ctrl,
 			.frontend_attach  = anysee_frontend_attach,
 			.tuner_attach     = anysee_tuner_attach,
@@ -1057,7 +1338,7 @@
 					}
 				}
 			},
-		}},
+		} },
 		}
 	},
 
@@ -1087,7 +1368,7 @@
 static struct usb_driver anysee_driver = {
 	.name       = "dvb_usb_anysee",
 	.probe      = anysee_probe,
-	.disconnect = dvb_usb_device_exit,
+	.disconnect = anysee_disconnect,
 	.id_table   = anysee_table,
 };
 
diff --git a/drivers/media/dvb/dvb-usb/anysee.h b/drivers/media/dvb/dvb-usb/anysee.h
index 57ee500..8ac8794 100644
--- a/drivers/media/dvb/dvb-usb/anysee.h
+++ b/drivers/media/dvb/dvb-usb/anysee.h
@@ -36,6 +36,7 @@
 
 #define DVB_USB_LOG_PREFIX "anysee"
 #include "dvb-usb.h"
+#include "dvb_ca_en50221.h"
 
 #define deb_info(args...) dprintk(dvb_usb_anysee_debug, 0x01, args)
 #define deb_xfer(args...) dprintk(dvb_usb_anysee_debug, 0x02, args)
@@ -54,12 +55,16 @@
 	CMD_GET_IR_CODE         = 0x41,
 	CMD_GET_HW_INFO         = 0x19,
 	CMD_SMARTCARD           = 0x34,
+	CMD_CI                  = 0x37,
 };
 
 struct anysee_state {
 	u8 hw; /* PCB ID */
 	u8 seq;
 	u8 fe_id:1; /* frondend ID */
+	u8 has_ci:1;
+	struct dvb_ca_en50221 ci;
+	unsigned long ci_cam_ready; /* jiffies */
 };
 
 #define ANYSEE_HW_507T    2 /* E30 */
@@ -69,6 +74,7 @@
 #define ANYSEE_HW_507FA  15 /* E30 Combo Plus / E30 C Plus */
 #define ANYSEE_HW_508TC  18 /* E7 TC */
 #define ANYSEE_HW_508S2  19 /* E7 S2 */
+#define ANYSEE_HW_508T2C 20 /* E7 T2C */
 #define ANYSEE_HW_508PTC 21 /* E7 PTC Plus */
 #define ANYSEE_HW_508PS2 22 /* E7 PS2 Plus */
 
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index f313182..d0174fd 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -1279,7 +1279,7 @@
 	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
 
 	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
-				0x80);
+				0x80, 0);
 
 	adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
 			      &dib807x_dib8000_config[0]);
@@ -1308,7 +1308,7 @@
 	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
 
 	/* initialize IC 0 */
-	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80);
+	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80, 0);
 
 	adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
 			      &dib807x_dib8000_config[0]);
@@ -1319,7 +1319,7 @@
 static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
 {
 	/* initialize IC 1 */
-	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82);
+	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82, 0);
 
 	adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82,
 			      &dib807x_dib8000_config[1]);
@@ -1328,7 +1328,7 @@
 }
 
 /* STK8096GP */
-struct dibx000_agc_config dib8090_agc_config[2] = {
+static struct dibx000_agc_config dib8090_agc_config[2] = {
 	{
 	BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
 	/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
@@ -1518,7 +1518,7 @@
 	if (ret < 0)
 		return ret;
 
-	target = (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2;
+	target = (dib0090_get_wbd_target(fe) * 8 * 18 / 33 + 1) / 2;
 	dib8000_set_wbd_ref(fe, target);
 
 
@@ -1578,7 +1578,7 @@
 	msleep(10);
 	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
 
-	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80);
+	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80, 0);
 
 	adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
 
@@ -1629,7 +1629,7 @@
 	msleep(20);
 	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
 
-	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80);
+	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80, 0);
 
 	adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
 	if (adap->fe_adap[0].fe == NULL)
@@ -1641,6 +1641,261 @@
 	return fe_slave == NULL ?  -ENODEV : 0;
 }
 
+/* TFE8096P */
+static struct dibx000_agc_config dib8096p_agc_config[2] = {
+	{
+		.band_caps		= BAND_UHF,
+		/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
+		   P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
+		   P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
+		   P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
+		   P_agc_write=0 */
+		.setup			= (0 << 15) | (0 << 14) | (5 << 11)
+			| (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5)
+			| (0 << 4) | (5 << 1) | (0 << 0),
+
+		.inv_gain		= 684,
+		.time_stabiliz	= 10,
+
+		.alpha_level	= 0,
+		.thlock			= 118,
+
+		.wbd_inv		= 0,
+		.wbd_ref		= 1200,
+		.wbd_sel		= 3,
+		.wbd_alpha		= 5,
+
+		.agc1_max		= 65535,
+		.agc1_min		= 0,
+
+		.agc2_max		= 32767,
+		.agc2_min		= 0,
+
+		.agc1_pt1		= 0,
+		.agc1_pt2		= 0,
+		.agc1_pt3		= 105,
+		.agc1_slope1	= 0,
+		.agc1_slope2	= 156,
+		.agc2_pt1		= 105,
+		.agc2_pt2		= 255,
+		.agc2_slope1	= 54,
+		.agc2_slope2	= 0,
+
+		.alpha_mant		= 28,
+		.alpha_exp		= 26,
+		.beta_mant		= 31,
+		.beta_exp		= 51,
+
+		.perform_agc_softsplit = 0,
+	} , {
+		.band_caps		= BAND_FM | BAND_VHF | BAND_CBAND,
+		/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
+		   P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
+		   P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
+		   P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
+		   P_agc_write=0 */
+		.setup			= (0 << 15) | (0 << 14) | (5 << 11)
+			| (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5)
+			| (0 << 4) | (5 << 1) | (0 << 0),
+
+		.inv_gain		= 732,
+		.time_stabiliz  = 10,
+
+		.alpha_level	= 0,
+		.thlock			= 118,
+
+		.wbd_inv		= 0,
+		.wbd_ref		= 1200,
+		.wbd_sel		= 3,
+		.wbd_alpha		= 5,
+
+		.agc1_max		= 65535,
+		.agc1_min		= 0,
+
+		.agc2_max		= 32767,
+		.agc2_min		= 0,
+
+		.agc1_pt1		= 0,
+		.agc1_pt2		= 0,
+		.agc1_pt3		= 98,
+		.agc1_slope1	= 0,
+		.agc1_slope2	= 167,
+		.agc2_pt1		= 98,
+		.agc2_pt2		= 255,
+		.agc2_slope1	= 52,
+		.agc2_slope2	= 0,
+
+		.alpha_mant		= 28,
+		.alpha_exp		= 26,
+		.beta_mant		= 31,
+		.beta_exp		= 51,
+
+		.perform_agc_softsplit = 0,
+	}
+};
+
+static struct dibx000_bandwidth_config dib8096p_clock_config_12_mhz = {
+	108000, 13500,
+	1, 9, 1, 0, 0,
+	0, 0, 0, 0, 2,
+	(3 << 14) | (1 << 12) | (524 << 0),
+	(0 << 25) | 0,
+	20199729,
+	12000000,
+};
+
+static struct dib8000_config tfe8096p_dib8000_config = {
+	.output_mpeg2_in_188_bytes	= 1,
+	.hostbus_diversity			= 1,
+	.update_lna					= NULL,
+
+	.agc_config_count			= 2,
+	.agc						= dib8096p_agc_config,
+	.pll						= &dib8096p_clock_config_12_mhz,
+
+	.gpio_dir					= DIB8000_GPIO_DEFAULT_DIRECTIONS,
+	.gpio_val					= DIB8000_GPIO_DEFAULT_VALUES,
+	.gpio_pwm_pos				= DIB8000_GPIO_DEFAULT_PWM_POS,
+
+	.agc_control				= NULL,
+	.diversity_delay			= 48,
+	.output_mode				= OUTMODE_MPEG2_FIFO,
+	.enMpegOutput				= 1,
+};
+
+static struct dib0090_wbd_slope dib8096p_wbd_table[] = {
+	{ 380, 81, 850, 64, 540, 4},
+	{ 860, 51, 866, 21, 375, 4},
+	{1700, 0, 250, 0, 100, 6},
+	{2600, 0, 250, 0, 100, 6},
+	{ 0xFFFF, 0, 0, 0, 0, 0},
+};
+
+static const struct dib0090_config tfe8096p_dib0090_config = {
+	.io.clock_khz			= 12000,
+	.io.pll_bypass			= 0,
+	.io.pll_range			= 0,
+	.io.pll_prediv			= 3,
+	.io.pll_loopdiv			= 6,
+	.io.adc_clock_ratio		= 0,
+	.io.pll_int_loop_filt	= 0,
+	.reset					= dib8096p_tuner_sleep,
+	.sleep					= dib8096p_tuner_sleep,
+
+	.freq_offset_khz_uhf	= -143,
+	.freq_offset_khz_vhf	= -143,
+
+	.get_adc_power			= dib8090_get_adc_power,
+
+	.clkouttobamse			= 1,
+	.analog_output			= 0,
+
+	.wbd_vhf_offset			= 0,
+	.wbd_cband_offset		= 0,
+	.use_pwm_agc			= 1,
+	.clkoutdrive			= 0,
+
+	.fref_clock_ratio		= 1,
+
+	.wbd					= dib8096p_wbd_table,
+
+	.ls_cfg_pad_drv			= 0,
+	.data_tx_drv			= 0,
+	.low_if					= NULL,
+	.in_soc					= 1,
+	.force_cband_input		= 0,
+};
+
+struct dibx090p_adc {
+	u32 freq;			/* RF freq MHz */
+	u32 timf;			/* New Timf */
+	u32 pll_loopdiv;	/* New prediv */
+	u32 pll_prediv;		/* New loopdiv */
+};
+
+struct dibx090p_adc dib8090p_adc_tab[] = {
+	{ 50000, 17043521, 16, 3}, /* 64 MHz */
+	{878000, 20199729, 9, 1}, /* 60 MHz */
+	{0xffffffff, 0, 0, 0}, /* 60 MHz */
+};
+
+static int dib8096p_agc_startup(struct dvb_frontend *fe,
+		struct dvb_frontend_parameters *fep)
+{
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
+	struct dib0700_adapter_state *state = adap->priv;
+	struct dibx000_bandwidth_config pll;
+	u16 target;
+	int better_sampling_freq = 0, ret;
+	struct dibx090p_adc *adc_table = &dib8090p_adc_tab[0];
+
+	ret = state->set_param_save(fe, fep);
+	if (ret < 0)
+		return ret;
+	memset(&pll, 0, sizeof(struct dibx000_bandwidth_config));
+
+	dib0090_pwm_gain_reset(fe);
+	/* dib0090_get_wbd_target is returning any possible
+	   temperature compensated wbd-target */
+	target = (dib0090_get_wbd_target(fe) * 8  + 1) / 2;
+	dib8000_set_wbd_ref(fe, target);
+
+
+	while (fep->frequency / 1000 > adc_table->freq) {
+		better_sampling_freq = 1;
+		adc_table++;
+	}
+
+	if ((adc_table->freq != 0xffffffff) && better_sampling_freq) {
+		pll.pll_ratio  = adc_table->pll_loopdiv;
+		pll.pll_prediv = adc_table->pll_prediv;
+		dib8000_update_pll(fe, &pll);
+		dib8000_ctrl_timf(fe, DEMOD_TIMF_SET, adc_table->timf);
+	}
+	return 0;
+}
+
+static int tfe8096p_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+	msleep(20);
+	dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+	dib0700_ctrl_clock(adap->dev, 72, 1);
+
+	msleep(20);
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+	msleep(20);
+	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80, 1);
+
+	adap->fe_adap[0].fe = dvb_attach(dib8000_attach,
+			&adap->dev->i2c_adap, 0x80, &tfe8096p_dib8000_config);
+
+	return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
+}
+
+static int tfe8096p_tuner_attach(struct dvb_usb_adapter *adap)
+{
+	struct dib0700_adapter_state *st = adap->priv;
+	struct i2c_adapter *tun_i2c = dib8096p_get_i2c_tuner(adap->fe_adap[0].fe);
+
+	if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c,
+				&tfe8096p_dib0090_config) == NULL)
+		return -ENODEV;
+
+	dib8000_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
+
+	st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
+	adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096p_agc_startup;
+	return 0;
+}
+
 /* STK9090M */
 static int dib90x0_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
 {
@@ -1883,7 +2138,7 @@
 	i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
 	if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0)
 		return -ENODEV;
-	dib0700_set_i2c_speed(adap->dev, 2000);
+	dib0700_set_i2c_speed(adap->dev, 1500);
 	if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0)
 		return -ENODEV;
 	release_firmware(state->frontend_firmware);
@@ -1962,7 +2217,8 @@
 	i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
 	if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0)
 		return -ENODEV;
-	dib0700_set_i2c_speed(adap->dev, 2000);
+
+	dib0700_set_i2c_speed(adap->dev, 1500);
 	if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0)
 		return -ENODEV;
 
@@ -1975,7 +2231,7 @@
 		if (dvb_attach(dib0090_fw_register, fe_slave, i2c, &nim9090md_dib0090_config[1]) == NULL)
 			return -ENODEV;
 		fe_slave->dvb = adap->fe_adap[0].fe->dvb;
-		dib9000_fw_set_component_bus_speed(adap->fe_adap[0].fe, 2000);
+		dib9000_fw_set_component_bus_speed(adap->fe_adap[0].fe, 1500);
 		if (dib9000_firmware_post_pll_init(fe_slave) < 0)
 			return -ENODEV;
 	}
@@ -2079,7 +2335,7 @@
 
 	memset(&pll, 0, sizeof(struct dibx000_bandwidth_config));
 	dib0090_pwm_gain_reset(fe);
-	target = (dib0090_get_wbd_offset(fe) * 8 + 1) / 2;
+	target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2;
 	dib7000p_set_wbd_ref(fe, target);
 
 	if (dib7090p_get_best_sampling(fe, &adc) == 0) {
@@ -2092,6 +2348,49 @@
 	return 0;
 }
 
+static int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
+{
+	deb_info("AGC restart callback: %d", restart);
+	if (restart == 0) /* before AGC startup */
+		dib0090_set_dc_servo(fe, 1);
+	return 0;
+}
+
+static int dib7090e_update_lna(struct dvb_frontend *fe, u16 agc_global)
+{
+	u16 agc1 = 0, agc2, wbd = 0, wbd_target, wbd_offset, threshold_agc1;
+	s16 wbd_delta;
+
+	if ((fe->dtv_property_cache.frequency) < 400000000)
+		threshold_agc1 = 25000;
+	else
+		threshold_agc1 = 30000;
+
+	wbd_target = (dib0090_get_wbd_target(fe)*8+1)/2;
+	wbd_offset = dib0090_get_wbd_offset(fe);
+	dib7000p_get_agc_values(fe, NULL, &agc1, &agc2, &wbd);
+	wbd_delta = (s16)wbd - (((s16)wbd_offset+10)*4) ;
+
+	deb_info("update lna, agc_global=%d agc1=%d agc2=%d",
+			agc_global, agc1, agc2);
+	deb_info("update lna, wbd=%d wbd target=%d wbd offset=%d wbd delta=%d",
+			wbd, wbd_target, wbd_offset, wbd_delta);
+
+	if ((agc1 < threshold_agc1) && (wbd_delta > 0)) {
+		dib0090_set_switch(fe, 1, 1, 1);
+		dib0090_set_vga(fe, 0);
+		dib0090_update_rframp_7090(fe, 0);
+		dib0090_update_tuning_table_7090(fe, 0);
+	} else {
+		dib0090_set_vga(fe, 1);
+		dib0090_update_rframp_7090(fe, 1);
+		dib0090_update_tuning_table_7090(fe, 1);
+		dib0090_set_switch(fe, 0, 0, 0);
+	}
+
+	return 0;
+}
+
 static struct dib0090_wbd_slope dib7090_wbd_table[] = {
 	{ 380,   81, 850, 64, 540,  4},
 	{ 860,   51, 866, 21,  375, 4},
@@ -2100,7 +2399,16 @@
 	{ 0xFFFF, 0,   0, 0,   0,   0},
 };
 
-struct dibx000_agc_config dib7090_agc_config[2] = {
+static struct dib0090_wbd_slope dib7090e_wbd_table[] = {
+	{ 380,   81, 850, 64, 540,	4},
+	{ 700,   51, 866, 21,  320,	4},
+	{ 860,   48, 666, 18,  330,	6},
+	{1700,    0, 250, 0,   100, 6},
+	{2600,    0, 250, 0,   100, 6},
+	{ 0xFFFF, 0,   0, 0,   0,	0},
+};
+
+static struct dibx000_agc_config dib7090_agc_config[2] = {
 	{
 		.band_caps      = BAND_UHF,
 		/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
@@ -2278,6 +2586,34 @@
 	}
 };
 
+static struct dib7000p_config tfe7090e_dib7000p_config = {
+	.output_mpeg2_in_188_bytes  = 1,
+	.hostbus_diversity			= 1,
+	.tuner_is_baseband			= 1,
+	.update_lna					= dib7090e_update_lna,
+
+	.agc_config_count			= 2,
+	.agc						= dib7090_agc_config,
+
+	.bw							= &dib7090_clock_config_12_mhz,
+
+	.gpio_dir					= DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+	.gpio_val					= DIB7000P_GPIO_DEFAULT_VALUES,
+	.gpio_pwm_pos				= DIB7000P_GPIO_DEFAULT_PWM_POS,
+
+	.pwm_freq_div				= 0,
+
+	.agc_control				= dib7090_agc_restart,
+
+	.spur_protect				= 0,
+	.disable_sample_and_hold	= 0,
+	.enable_current_mirror		= 0,
+	.diversity_delay			= 0,
+
+	.output_mode				= OUTMODE_MPEG2_FIFO,
+	.enMpegOutput				= 1,
+};
+
 static const struct dib0090_config nim7090_dib0090_config = {
 	.io.clock_khz = 12000,
 	.io.pll_bypass = 0,
@@ -2312,6 +2648,107 @@
 	.in_soc = 1,
 };
 
+static const struct dib0090_config tfe7090e_dib0090_config = {
+	.io.clock_khz = 12000,
+	.io.pll_bypass = 0,
+	.io.pll_range = 0,
+	.io.pll_prediv = 3,
+	.io.pll_loopdiv = 6,
+	.io.adc_clock_ratio = 0,
+	.io.pll_int_loop_filt = 0,
+	.reset = dib7090_tuner_sleep,
+	.sleep = dib7090_tuner_sleep,
+
+	.freq_offset_khz_uhf = 0,
+	.freq_offset_khz_vhf = 0,
+
+	.get_adc_power = dib7090_get_adc_power,
+
+	.clkouttobamse = 1,
+	.analog_output = 0,
+
+	.wbd_vhf_offset = 0,
+	.wbd_cband_offset = 0,
+	.use_pwm_agc = 1,
+	.clkoutdrive = 0,
+
+	.fref_clock_ratio = 0,
+
+	.wbd = dib7090e_wbd_table,
+
+	.ls_cfg_pad_drv = 0,
+	.data_tx_drv = 0,
+	.low_if = NULL,
+	.in_soc = 1,
+	.force_cband_input = 1,
+	.is_dib7090e = 1,
+};
+
+static struct dib7000p_config tfe7790e_dib7000p_config = {
+	.output_mpeg2_in_188_bytes  = 1,
+	.hostbus_diversity			= 1,
+	.tuner_is_baseband			= 1,
+	.update_lna					= dib7090e_update_lna,
+
+	.agc_config_count			= 2,
+	.agc						= dib7090_agc_config,
+
+	.bw							= &dib7090_clock_config_12_mhz,
+
+	.gpio_dir					= DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+	.gpio_val					= DIB7000P_GPIO_DEFAULT_VALUES,
+	.gpio_pwm_pos				= DIB7000P_GPIO_DEFAULT_PWM_POS,
+
+	.pwm_freq_div				= 0,
+
+	.agc_control				= dib7090_agc_restart,
+
+	.spur_protect				= 0,
+	.disable_sample_and_hold	= 0,
+	.enable_current_mirror		= 0,
+	.diversity_delay			= 0,
+
+	.output_mode				= OUTMODE_MPEG2_PAR_GATED_CLK,
+	.enMpegOutput				= 1,
+};
+
+static const struct dib0090_config tfe7790e_dib0090_config = {
+	.io.clock_khz = 12000,
+	.io.pll_bypass = 0,
+	.io.pll_range = 0,
+	.io.pll_prediv = 3,
+	.io.pll_loopdiv = 6,
+	.io.adc_clock_ratio = 0,
+	.io.pll_int_loop_filt = 0,
+	.reset = dib7090_tuner_sleep,
+	.sleep = dib7090_tuner_sleep,
+
+	.freq_offset_khz_uhf = 0,
+	.freq_offset_khz_vhf = 0,
+
+	.get_adc_power = dib7090_get_adc_power,
+
+	.clkouttobamse = 1,
+	.analog_output = 0,
+
+	.wbd_vhf_offset = 0,
+	.wbd_cband_offset = 0,
+	.use_pwm_agc = 1,
+	.clkoutdrive = 0,
+
+	.fref_clock_ratio = 0,
+
+	.wbd = dib7090e_wbd_table,
+
+	.ls_cfg_pad_drv = 0,
+	.data_tx_drv = 0,
+	.low_if = NULL,
+	.in_soc = 1,
+	.force_cband_input = 1,
+	.is_dib7090e = 1,
+	.force_crystal_mode = 1,
+};
+
 static const struct dib0090_config tfe7090pvr_dib0090_config[2] = {
 	{
 		.io.clock_khz = 12000,
@@ -2504,6 +2941,97 @@
 	return 0;
 }
 
+static int tfe7090e_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+	msleep(20);
+	dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+	msleep(20);
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+	msleep(20);
+	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+	if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap,
+				1, 0x10, &tfe7090e_dib7000p_config) != 0) {
+		err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
+				__func__);
+		return -ENODEV;
+	}
+	adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
+			0x80, &tfe7090e_dib7000p_config);
+
+	return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
+}
+
+static int tfe7790e_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	struct dib0700_state *st = adap->dev->priv;
+
+	/* The TFE7790E requires the dib0700 to not be in master mode */
+	st->disable_streaming_master_mode = 1;
+
+	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+	msleep(20);
+	dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+	msleep(20);
+	dib0700_ctrl_clock(adap->dev, 72, 1);
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+	msleep(20);
+	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+	if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap,
+				1, 0x10, &tfe7790e_dib7000p_config) != 0) {
+		err("%s: dib7000p_i2c_enumeration failed.  Cannot continue\n",
+				__func__);
+		return -ENODEV;
+	}
+	adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
+			0x80, &tfe7790e_dib7000p_config);
+
+	return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
+}
+
+static int tfe7790e_tuner_attach(struct dvb_usb_adapter *adap)
+{
+	struct dib0700_adapter_state *st = adap->priv;
+	struct i2c_adapter *tun_i2c =
+		dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
+
+	if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c,
+				&tfe7790e_dib0090_config) == NULL)
+		return -ENODEV;
+
+	dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
+
+	st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
+	adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
+	return 0;
+}
+
+static int tfe7090e_tuner_attach(struct dvb_usb_adapter *adap)
+{
+	struct dib0700_adapter_state *st = adap->priv;
+	struct i2c_adapter *tun_i2c =
+		dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
+
+	if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c,
+				&tfe7090e_dib0090_config) == NULL)
+		return -ENODEV;
+
+	dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
+
+	st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
+	adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
+	return 0;
+}
+
 /* STK7070PD */
 static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
 	{
@@ -2960,6 +3488,9 @@
 /* 75 */{ USB_DEVICE(USB_VID_MEDION,    USB_PID_CREATIX_CTX1921) },
 	{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV340E) },
 	{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV340E_SE) },
+	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_TFE7090E) },
+	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_TFE7790E) },
+/* 80 */{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_TFE8096P) },
 	{ 0 }		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -4025,6 +4556,127 @@
 					    RC_TYPE_NEC,
 			.change_protocol  = dib0700_change_protocol,
 		},
+	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+		.num_adapters = 1,
+		.adapter = {
+			{
+				.num_frontends = 1,
+				.fe = {{
+					.caps  = DVB_USB_ADAP_HAS_PID_FILTER |
+						DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+					.pid_filter_count = 32,
+					.pid_filter = stk70x0p_pid_filter,
+					.pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
+					.frontend_attach  = tfe7090e_frontend_attach,
+					.tuner_attach     = tfe7090e_tuner_attach,
+
+					DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+				} },
+
+				.size_of_priv =
+					sizeof(struct dib0700_adapter_state),
+			},
+		},
+
+		.num_device_descs = 1,
+		.devices = {
+			{   "DiBcom TFE7090E reference design",
+				{ &dib0700_usb_id_table[78], NULL },
+				{ NULL },
+			},
+		},
+
+		.rc.core = {
+			.rc_interval      = DEFAULT_RC_INTERVAL,
+			.rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+			.module_name	  = "dib0700",
+			.rc_query         = dib0700_rc_query_old_firmware,
+			.allowed_protos   = RC_TYPE_RC5 |
+					    RC_TYPE_RC6 |
+					    RC_TYPE_NEC,
+			.change_protocol  = dib0700_change_protocol,
+		},
+	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+		.num_adapters = 1,
+		.adapter = {
+			{
+				.num_frontends = 1,
+				.fe = {{
+					.caps  = DVB_USB_ADAP_HAS_PID_FILTER |
+						DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+					.pid_filter_count = 32,
+					.pid_filter = stk70x0p_pid_filter,
+					.pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
+					.frontend_attach  = tfe7790e_frontend_attach,
+					.tuner_attach     = tfe7790e_tuner_attach,
+
+					DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
+				} },
+
+				.size_of_priv =
+					sizeof(struct dib0700_adapter_state),
+			},
+		},
+
+		.num_device_descs = 1,
+		.devices = {
+			{   "DiBcom TFE7790E reference design",
+				{ &dib0700_usb_id_table[79], NULL },
+				{ NULL },
+			},
+		},
+
+		.rc.core = {
+			.rc_interval      = DEFAULT_RC_INTERVAL,
+			.rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+			.module_name	  = "dib0700",
+			.rc_query         = dib0700_rc_query_old_firmware,
+			.allowed_protos   = RC_TYPE_RC5 |
+					    RC_TYPE_RC6 |
+					    RC_TYPE_NEC,
+			.change_protocol  = dib0700_change_protocol,
+		},
+	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+		.num_adapters = 1,
+		.adapter = {
+			{
+				.num_frontends = 1,
+				.fe = {{
+					.caps  = DVB_USB_ADAP_HAS_PID_FILTER |
+						DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+					.pid_filter_count = 32,
+					.pid_filter = stk80xx_pid_filter,
+					.pid_filter_ctrl = stk80xx_pid_filter_ctrl,
+					.frontend_attach  = tfe8096p_frontend_attach,
+					.tuner_attach     = tfe8096p_tuner_attach,
+
+					DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+				} },
+
+				.size_of_priv =
+					sizeof(struct dib0700_adapter_state),
+			},
+		},
+
+		.num_device_descs = 1,
+		.devices = {
+			{   "DiBcom TFE8096P reference design",
+				{ &dib0700_usb_id_table[80], NULL },
+				{ NULL },
+			},
+		},
+
+		.rc.core = {
+			.rc_interval      = DEFAULT_RC_INTERVAL,
+			.rc_codes         = RC_MAP_DIB0700_RC5_TABLE,
+			.module_name	  = "dib0700",
+			.rc_query         = dib0700_rc_query_old_firmware,
+			.allowed_protos   = RC_TYPE_RC5 |
+					    RC_TYPE_RC6 |
+					    RC_TYPE_NEC,
+			.change_protocol  = dib0700_change_protocol,
+		},
 	},
 };
 
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 2d08c9b..3cce13bb 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -109,10 +109,13 @@
 #define USB_PID_DIBCOM_STK807XPVR			0x1f98
 #define USB_PID_DIBCOM_STK8096GP                        0x1fa0
 #define USB_PID_DIBCOM_NIM8096MD                        0x1fa8
+#define USB_PID_DIBCOM_TFE8096P				0x1f9C
 #define USB_PID_DIBCOM_ANCHOR_2135_COLD			0x2131
 #define USB_PID_DIBCOM_STK7770P				0x1e80
 #define USB_PID_DIBCOM_NIM7090				0x1bb2
 #define USB_PID_DIBCOM_TFE7090PVR			0x1bb4
+#define USB_PID_DIBCOM_TFE7090E				0x1bb7
+#define USB_PID_DIBCOM_TFE7790E				0x1e6e
 #define USB_PID_DIBCOM_NIM9090M				0x2383
 #define USB_PID_DIBCOM_NIM9090MD			0x2384
 #define USB_PID_DPOSH_M9206_COLD			0x9206
@@ -128,6 +131,7 @@
 #define USB_PID_GRANDTEC_DVBT_USB_WARM			0x0fa1
 #define USB_PID_INTEL_CE9500				0x9500
 #define USB_PID_ITETECH_IT9135				0x9135
+#define USB_PID_ITETECH_IT9135_9005			0x9005
 #define USB_PID_KWORLD_399U				0xe399
 #define USB_PID_KWORLD_399U_2				0xe400
 #define USB_PID_KWORLD_395U				0xe396
@@ -322,6 +326,7 @@
 #define USB_PID_TVWAY_PLUS				0x0002
 #define USB_PID_SVEON_STV20				0xe39d
 #define USB_PID_SVEON_STV22				0xe401
+#define USB_PID_SVEON_STV22_IT9137			0xe411
 #define USB_PID_AZUREWAVE_AZ6027			0x3275
 #define USB_PID_TERRATEC_DVBS2CI_V1			0x10a4
 #define USB_PID_TERRATEC_DVBS2CI_V2			0x10ac
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index f103ec1..41cff37 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -1859,12 +1859,11 @@
 static int dw2102_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 {
-	p1100 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
+	p1100 = kmemdup(&s6x0_properties,
+			sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
 	if (!p1100)
 		return -ENOMEM;
 	/* copy default structure */
-	memcpy(p1100, &s6x0_properties,
-			sizeof(struct dvb_usb_device_properties));
 	/* fill only different fields */
 	p1100->firmware = "dvb-usb-p1100.fw";
 	p1100->devices[0] = d1100;
@@ -1872,13 +1871,12 @@
 	p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table);
 	p1100->adapter->fe[0].frontend_attach = stv0288_frontend_attach;
 
-	s660 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
+	s660 = kmemdup(&s6x0_properties,
+		       sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
 	if (!s660) {
 		kfree(p1100);
 		return -ENOMEM;
 	}
-	memcpy(s660, &s6x0_properties,
-			sizeof(struct dvb_usb_device_properties));
 	s660->firmware = "dvb-usb-s660.fw";
 	s660->num_device_descs = 3;
 	s660->devices[0] = d660;
@@ -1886,14 +1884,13 @@
 	s660->devices[2] = d480_2;
 	s660->adapter->fe[0].frontend_attach = ds3000_frontend_attach;
 
-	p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
+	p7500 = kmemdup(&s6x0_properties,
+			sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
 	if (!p7500) {
 		kfree(p1100);
 		kfree(s660);
 		return -ENOMEM;
 	}
-	memcpy(p7500, &s6x0_properties,
-			sizeof(struct dvb_usb_device_properties));
 	p7500->firmware = "dvb-usb-p7500.fw";
 	p7500->devices[0] = d7500;
 	p7500->rc.legacy.rc_map_table = rc_map_tbs_table;
diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c
index c462261..47317e9 100644
--- a/drivers/media/dvb/dvb-usb/it913x.c
+++ b/drivers/media/dvb/dvb-usb/it913x.c
@@ -52,42 +52,59 @@
 module_param_named(pid, pid_filter, int, 0644);
 MODULE_PARM_DESC(pid, "set default 0=on 1=off");
 
+static int dvb_usb_it913x_firmware;
+module_param_named(firmware, dvb_usb_it913x_firmware, int, 0644);
+MODULE_PARM_DESC(firmware, "set firmware 0=auto 1=IT9137 2=IT9135V1");
+
+
 int cmd_counter;
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 struct it913x_state {
 	u8 id;
-};
-
-struct ite_config {
-	u8 chip_ver;
-	u16 chip_type;
-	u32 firmware;
-	u8 tuner_id_0;
-	u8 tuner_id_1;
-	u8 dual_mode;
+	struct ite_config it913x_config;
 };
 
 struct ite_config it913x_config;
 
+#define IT913X_RETRY	10
+#define IT913X_SND_TIMEOUT	100
+#define IT913X_RCV_TIMEOUT	200
+
 static int it913x_bulk_write(struct usb_device *dev,
 				u8 *snd, int len, u8 pipe)
 {
-	int ret, actual_l;
+	int ret, actual_l, i;
 
-	ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe),
-				snd, len , &actual_l, 100);
+	for (i = 0; i < IT913X_RETRY; i++) {
+		ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe),
+				snd, len , &actual_l, IT913X_SND_TIMEOUT);
+		if (ret == 0 || ret != -EBUSY || ret != -ETIMEDOUT)
+			break;
+	}
+
+	if (len != actual_l && ret == 0)
+		ret = -EAGAIN;
+
 	return ret;
 }
 
 static int it913x_bulk_read(struct usb_device *dev,
 				u8 *rev, int len, u8 pipe)
 {
-	int ret, actual_l;
+	int ret, actual_l, i;
 
-	ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe),
-				 rev, len , &actual_l, 200);
+	for (i = 0; i < IT913X_RETRY; i++) {
+		ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe),
+				 rev, len , &actual_l, IT913X_RCV_TIMEOUT);
+		if (ret == 0 || ret != -EBUSY || ret != -ETIMEDOUT)
+			break;
+	}
+
+	if (len != actual_l && ret == 0)
+		ret = -EAGAIN;
+
 	return ret;
 }
 
@@ -100,7 +117,7 @@
 	return ~sum;
 }
 
-static int it913x_io(struct usb_device *udev, u8 mode, u8 pro,
+static int it913x_usb_talk(struct usb_device *udev, u8 mode, u8 pro,
 			u8 cmd, u32 reg, u8 addr, u8 *data, u8 len)
 {
 	int ret = 0, i, buf_size = 1;
@@ -159,22 +176,41 @@
 	buff[buf_size++] = (chk_sum & 0xff);
 
 	ret = it913x_bulk_write(udev, buff, buf_size , 0x02);
+	if (ret < 0)
+		goto error;
 
-	ret |= it913x_bulk_read(udev, buff, (mode & 1) ?
+	ret = it913x_bulk_read(udev, buff, (mode & 1) ?
 			5 : len + 5 , 0x01);
+	if (ret < 0)
+		goto error;
 
 	rlen = (mode & 0x1) ? 0x1 : len;
 
 	if (mode & 1)
-		ret |= buff[2];
+		ret = buff[2];
 	else
 		memcpy(data, &buff[3], rlen);
 
 	cmd_counter++;
 
-	kfree(buff);
+error:	kfree(buff);
 
-	return (ret < 0) ? -ENODEV : 0;
+	return ret;
+}
+
+static int it913x_io(struct usb_device *udev, u8 mode, u8 pro,
+			u8 cmd, u32 reg, u8 addr, u8 *data, u8 len)
+{
+	int ret, i;
+
+	for (i = 0; i < IT913X_RETRY; i++) {
+		ret = it913x_usb_talk(udev, mode, pro,
+			cmd, reg, addr, data, len);
+		if (ret != -EAGAIN)
+			break;
+	}
+
+	return ret;
 }
 
 static int it913x_wr_reg(struct usb_device *udev, u8 pro, u32 reg , u8 data)
@@ -337,15 +373,62 @@
 
 	if ((ibuf[2] + ibuf[3]) == 0xff) {
 		key = ibuf[2];
-		key += ibuf[0] << 8;
-		deb_info(1, "INT Key =%08x", key);
+		key += ibuf[0] << 16;
+		key += ibuf[1] << 8;
+		deb_info(1, "NEC Extended Key =%08x", key);
 		if (d->rc_dev != NULL)
 			rc_keydown(d->rc_dev, key, 0);
 	}
+
 	mutex_unlock(&d->i2c_mutex);
 
 	return ret;
 }
+
+/* Firmware sets raw */
+const char fw_it9135_v1[] = "dvb-usb-it9135-01.fw";
+const char fw_it9137[] = "dvb-usb-it9137-01.fw";
+
+static int ite_firmware_select(struct usb_device *udev,
+	struct dvb_usb_device_properties *props)
+{
+	int sw;
+	/* auto switch */
+	if (le16_to_cpu(udev->descriptor.idProduct) ==
+			USB_PID_ITETECH_IT9135)
+		sw = IT9135_V1_FW;
+	else if (le16_to_cpu(udev->descriptor.idProduct) ==
+			USB_PID_ITETECH_IT9135_9005)
+		sw = IT9135_V1_FW;
+	else
+		sw = IT9137_FW;
+
+	/* force switch */
+	if (dvb_usb_it913x_firmware != IT9135_AUTO)
+		sw = dvb_usb_it913x_firmware;
+
+	switch (sw) {
+	case IT9135_V1_FW:
+		it913x_config.firmware_ver = 1;
+		it913x_config.adc_x2 = 1;
+		props->firmware = fw_it9135_v1;
+		break;
+	case IT9137_FW:
+	default:
+		it913x_config.firmware_ver = 0;
+		it913x_config.adc_x2 = 0;
+		props->firmware = fw_it9137;
+	}
+
+	return 0;
+}
+
+#define TS_MPEG_PKT_SIZE	188
+#define EP_LOW			21
+#define TS_BUFFER_SIZE_PID	(EP_LOW*TS_MPEG_PKT_SIZE)
+#define EP_HIGH			348
+#define TS_BUFFER_SIZE_MAX	(EP_HIGH*TS_MPEG_PKT_SIZE)
+
 static int it913x_identify_state(struct usb_device *udev,
 		struct dvb_usb_device_properties *props,
 		struct dvb_usb_device_description **desc,
@@ -359,6 +442,19 @@
 	/* checnk for dual mode */
 	it913x_config.dual_mode =  it913x_read_reg(udev, 0x49c5);
 
+	if (udev->speed != USB_SPEED_HIGH) {
+		props->adapter[0].fe[0].pid_filter_count = 5;
+		info("USB 1 low speed mode - connect to USB 2 port");
+		if (pid_filter > 0)
+			pid_filter = 0;
+		if (it913x_config.dual_mode) {
+			it913x_config.dual_mode = 0;
+			info("Dual mode not supported in USB 1");
+		}
+	} else /* For replugging */
+		if(props->adapter[0].fe[0].pid_filter_count == 5)
+			props->adapter[0].fe[0].pid_filter_count = 31;
+
 	/* TODO different remotes */
 	remote = it913x_read_reg(udev, 0x49ac); /* Remote */
 	if (remote == 0)
@@ -370,6 +466,19 @@
 	info("Dual mode=%x Remote=%x Tuner Type=%x", it913x_config.dual_mode
 		, remote, it913x_config.tuner_id_0);
 
+	/* Select Stream Buffer Size */
+	if (pid_filter)
+		props->adapter[0].fe[0].stream.u.bulk.buffersize =
+			TS_BUFFER_SIZE_MAX;
+	else
+		props->adapter[0].fe[0].stream.u.bulk.buffersize =
+			TS_BUFFER_SIZE_PID;
+	if (it913x_config.dual_mode)
+		props->adapter[1].fe[0].stream.u.bulk.buffersize =
+			props->adapter[0].fe[0].stream.u.bulk.buffersize;
+
+	ret = ite_firmware_select(udev, props);
+
 	if (firm_no > 0) {
 		*cold = 0;
 		return 0;
@@ -390,8 +499,8 @@
 			if (ret != 0)
 				ret = it913x_wr_reg(udev, DEV_0,
 					GPIOH1_O, 0x0);
+			props->num_adapters = 2;
 		}
-		props->num_adapters = 2;
 	} else
 		props->num_adapters = 1;
 
@@ -399,10 +508,16 @@
 
 	if (it913x_config.dual_mode) {
 		ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, CHIP2_I2C_ADDR);
-		ret |= it913x_wr_reg(udev, DEV_0,  CLK_O_EN, 0x1);
+		if (it913x_config.firmware_ver == 1)
+			ret |= it913x_wr_reg(udev, DEV_0,  0xcfff, 0x1);
+		else
+			ret |= it913x_wr_reg(udev, DEV_0,  CLK_O_EN, 0x1);
 	} else {
 		ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, 0x0);
-		ret |= it913x_wr_reg(udev, DEV_0,  CLK_O_EN, 0x0);
+		if (it913x_config.firmware_ver == 1)
+			ret |= it913x_wr_reg(udev, DEV_0,  0xcfff, 0x0);
+		else
+			ret |= it913x_wr_reg(udev, DEV_0,  CLK_O_EN, 0x0);
 	}
 
 	*cold = 1;
@@ -428,35 +543,40 @@
 	return ret;
 }
 
-
 static int it913x_download_firmware(struct usb_device *udev,
 					const struct firmware *fw)
 {
-	int ret = 0, i;
-	u8 packet_size, dlen;
+	int ret = 0, i = 0, pos = 0;
+	u8 packet_size;
 	u8 *fw_data;
 
-	packet_size = 0x29;
-
 	ret = it913x_wr_reg(udev, DEV_0,  I2C_CLK, I2C_CLK_100);
 
 	info("FRM Starting Firmware Download");
-	/* This uses scatter write firmware headers follow */
-	/* 03 XX 00     XX = chip number? */ 
 
-	for (i = 0; i < fw->size; i += packet_size) {
-			if (i > 0)
-				packet_size = 0x39;
-			fw_data = (u8 *)(fw->data + i);
-			dlen = ((i + packet_size) > fw->size)
-				? (fw->size - i) : packet_size;
-			ret |= it913x_io(udev, WRITE_DATA, DEV_0,
-				CMD_SCATTER_WRITE, 0, 0, fw_data, dlen);
-			udelay(1000);
+	/* Multi firmware loader */
+	/* This uses scatter write firmware headers */
+	/* The firmware must start with 03 XX 00 */
+	/* and be the extact firmware length */
+
+	while (i <= fw->size) {
+		if (((fw->data[i] == 0x3) && (fw->data[i + 2] == 0x0))
+			|| (i == fw->size)) {
+			packet_size = i - pos;
+			if ((packet_size > 0x19) || (i == fw->size)) {
+				fw_data = (u8 *)(fw->data + pos);
+				pos += packet_size;
+				if (packet_size > 0)
+					ret |= it913x_io(udev, WRITE_DATA,
+						DEV_0, CMD_SCATTER_WRITE, 0,
+						0, fw_data, packet_size);
+				udelay(1000);
+			}
+		}
+		i++;
 	}
 
-	ret |= it913x_io(udev, WRITE_CMD, DEV_0,
-			CMD_BOOT, 0, 0, NULL, 0);
+	ret |= it913x_io(udev, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0);
 
 	msleep(100);
 
@@ -474,12 +594,17 @@
 	/* Tuner function */
 	if (it913x_config.dual_mode)
 		ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0xa0);
+	else
+		ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0x68);
 
-	ret |= it913x_wr_reg(udev, DEV_0,  PADODPU, 0x0);
-	ret |= it913x_wr_reg(udev, DEV_0,  AGC_O_D, 0x0);
-	if (it913x_config.dual_mode) {
-		ret |= it913x_wr_reg(udev, DEV_1,  PADODPU, 0x0);
-		ret |= it913x_wr_reg(udev, DEV_1,  AGC_O_D, 0x0);
+	if ((it913x_config.chip_ver == 1) &&
+		(it913x_config.chip_type == 0x9135)) {
+		ret |= it913x_wr_reg(udev, DEV_0,  PADODPU, 0x0);
+		ret |= it913x_wr_reg(udev, DEV_0,  AGC_O_D, 0x0);
+		if (it913x_config.dual_mode) {
+			ret |= it913x_wr_reg(udev, DEV_1,  PADODPU, 0x0);
+			ret |= it913x_wr_reg(udev, DEV_1,  AGC_O_D, 0x0);
+		}
 	}
 
 	return (ret < 0) ? -ENODEV : 0;
@@ -500,32 +625,23 @@
 static int it913x_frontend_attach(struct dvb_usb_adapter *adap)
 {
 	struct usb_device *udev = adap->dev->udev;
+	struct it913x_state *st = adap->dev->priv;
 	int ret = 0;
-	u8 adf = it913x_read_reg(udev, IO_MUX_POWER_CLK);
 	u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5);
-	u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize;
-	u8 tuner_id, tuner_type;
+	u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize / 4;
+	u8 pkt_size = 0x80;
+
+	if (adap->dev->udev->speed != USB_SPEED_HIGH)
+		pkt_size = 0x10;
+
+	it913x_config.adf = it913x_read_reg(udev, IO_MUX_POWER_CLK);
 
 	if (adap->id == 0)
-		tuner_id = it913x_config.tuner_id_0;
-	else
-		tuner_id = it913x_config.tuner_id_1;
-
-	/* TODO we always use IT9137 possible references here*/
-	/* Documentation suggests don't care */
-	switch (tuner_id) {
-	case 0x51:
-	case 0x52:
-	case 0x60:
-	case 0x61:
-	case 0x62:
-	default:
-	case 0x38:
-		tuner_type = IT9137;
-	}
+		memcpy(&st->it913x_config, &it913x_config,
+			sizeof(struct ite_config));
 
 	adap->fe_adap[0].fe = dvb_attach(it913x_fe_attach,
-		&adap->dev->i2c_adap, adap_addr, adf, tuner_type);
+		&adap->dev->i2c_adap, adap_addr, &st->it913x_config);
 
 	if (adap->id == 0 && adap->fe_adap[0].fe) {
 		ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2_SW_RST, 0x1);
@@ -536,13 +652,13 @@
 		ret = it913x_wr_reg(udev, DEV_0, EP4_TX_LEN_LSB,
 					ep_size & 0xff);
 		ret = it913x_wr_reg(udev, DEV_0, EP4_TX_LEN_MSB, ep_size >> 8);
-		ret = it913x_wr_reg(udev, DEV_0, EP4_MAX_PKT, 0x80);
+		ret = it913x_wr_reg(udev, DEV_0, EP4_MAX_PKT, pkt_size);
 	} else if (adap->id == 1 && adap->fe_adap[0].fe) {
 		ret = it913x_wr_reg(udev, DEV_0, EP0_TX_EN, 0x6f);
 		ret = it913x_wr_reg(udev, DEV_0, EP5_TX_LEN_LSB,
 					ep_size & 0xff);
 		ret = it913x_wr_reg(udev, DEV_0, EP5_TX_LEN_MSB, ep_size >> 8);
-		ret = it913x_wr_reg(udev, DEV_0, EP5_MAX_PKT, 0x80);
+		ret = it913x_wr_reg(udev, DEV_0, EP5_MAX_PKT, pkt_size);
 		ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2IF2_EN, 0x1);
 		ret = it913x_wr_reg(udev, DEV_1_DMOD, MP2IF_SERIAL, 0x1);
 		ret = it913x_wr_reg(udev, DEV_1, TOP_HOSTB_SER_MODE, 0x1);
@@ -582,6 +698,8 @@
 static struct usb_device_id it913x_table[] = {
 	{ USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09) },
 	{ USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135) },
+	{ USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22_IT9137) },
+	{ USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9005) },
 	{}		/* Terminating entry */
 };
 
@@ -614,8 +732,8 @@
 				.endpoint = 0x04,
 				.u = {/* Keep Low if PID filter on */
 					.bulk = {
-						.buffersize = 3584,
-
+					.buffersize =
+						TS_BUFFER_SIZE_PID,
 					}
 				}
 			}
@@ -639,8 +757,8 @@
 				.endpoint = 0x05,
 				.u = {
 					.bulk = {
-						.buffersize = 3584,
-
+						.buffersize =
+							TS_BUFFER_SIZE_PID,
 					}
 				}
 			}
@@ -654,10 +772,10 @@
 		.rc_query	= it913x_rc_query,
 		.rc_interval	= IT913X_POLL,
 		.allowed_protos	= RC_TYPE_NEC,
-		.rc_codes	= RC_MAP_KWORLD_315U,
+		.rc_codes	= RC_MAP_MSI_DIGIVOX_III,
 	},
 	.i2c_algo         = &it913x_i2c_algo,
-	.num_device_descs = 2,
+	.num_device_descs = 3,
 	.devices = {
 		{   "Kworld UB499-2T T09(IT9137)",
 			{ &it913x_table[0], NULL },
@@ -665,6 +783,12 @@
 		{   "ITE 9135 Generic",
 			{ &it913x_table[1], NULL },
 			},
+		{   "Sveon STV22 Dual DVB-T HDTV(IT9137)",
+			{ &it913x_table[2], NULL },
+			},
+		{   "ITE 9135(9005) Generic",
+			{ &it913x_table[3], NULL },
+			},
 	}
 };
 
@@ -698,5 +822,5 @@
 
 MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
 MODULE_DESCRIPTION("it913x USB 2 Driver");
-MODULE_VERSION("1.07");
+MODULE_VERSION("1.14");
 MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c b/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c
index a634105..3bfc6d8 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c
+++ b/drivers/media/dvb/dvb-usb/mxl111sf-tuner.c
@@ -38,6 +38,8 @@
 
 	struct mxl111sf_tuner_config *cfg;
 
+	enum mxl_if_freq if_freq;
+
 	u32 frequency;
 	u32 bandwidth;
 };
@@ -186,7 +188,10 @@
 	ctrl = iffcw & 0x00ff;
 #endif
 	ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_REG, ctrl);
-	mxl_fail(ret);
+	if (mxl_fail(ret))
+		goto fail;
+
+	state->if_freq = state->cfg->if_freq;
 fail:
 	return ret;
 }
@@ -407,6 +412,54 @@
 	return 0;
 }
 
+static int mxl111sf_tuner_get_if_frequency(struct dvb_frontend *fe,
+					   u32 *frequency)
+{
+	struct mxl111sf_tuner_state *state = fe->tuner_priv;
+
+	*frequency = 0;
+
+	switch (state->if_freq) {
+	case MXL_IF_4_0:   /* 4.0   MHz */
+		*frequency = 4000000;
+		break;
+	case MXL_IF_4_5:   /* 4.5   MHz */
+		*frequency = 4500000;
+		break;
+	case MXL_IF_4_57:  /* 4.57  MHz */
+		*frequency = 4570000;
+		break;
+	case MXL_IF_5_0:   /* 5.0   MHz */
+		*frequency = 5000000;
+		break;
+	case MXL_IF_5_38:  /* 5.38  MHz */
+		*frequency = 5380000;
+		break;
+	case MXL_IF_6_0:   /* 6.0   MHz */
+		*frequency = 6000000;
+		break;
+	case MXL_IF_6_28:  /* 6.28  MHz */
+		*frequency = 6280000;
+		break;
+	case MXL_IF_7_2:   /* 7.2   MHz */
+		*frequency = 7200000;
+		break;
+	case MXL_IF_35_25: /* 35.25 MHz */
+		*frequency = 35250000;
+		break;
+	case MXL_IF_36:    /* 36    MHz */
+		*frequency = 36000000;
+		break;
+	case MXL_IF_36_15: /* 36.15 MHz */
+		*frequency = 36150000;
+		break;
+	case MXL_IF_44:    /* 44    MHz */
+		*frequency = 44000000;
+		break;
+	}
+	return 0;
+}
+
 static int mxl111sf_tuner_release(struct dvb_frontend *fe)
 {
 	struct mxl111sf_tuner_state *state = fe->tuner_priv;
@@ -436,6 +489,7 @@
 	.get_rf_strength   = mxl111sf_get_rf_strength,
 	.get_frequency     = mxl111sf_tuner_get_frequency,
 	.get_bandwidth     = mxl111sf_tuner_get_bandwidth,
+	.get_if_frequency  = mxl111sf_tuner_get_if_frequency,
 	.release           = mxl111sf_tuner_release,
 };
 
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf.c b/drivers/media/dvb/dvb-usb/mxl111sf.c
index b5c98da..34e6f8d 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf.c
+++ b/drivers/media/dvb/dvb-usb/mxl111sf.c
@@ -758,6 +758,7 @@
 
 
 #define MXL111SF_EP4_BULK_STREAMING_CONFIG		\
+	.size_of_priv = sizeof(struct mxl111sf_adap_state), \
 	.streaming_ctrl = mxl111sf_ep4_streaming_ctrl,	\
 	.stream = {					\
 		.type = USB_BULK,			\
@@ -772,6 +773,7 @@
 
 /* FIXME: works for v6 but not v8 silicon */
 #define MXL111SF_EP4_ISOC_STREAMING_CONFIG		\
+	.size_of_priv = sizeof(struct mxl111sf_adap_state), \
 	.streaming_ctrl = mxl111sf_ep4_streaming_ctrl,	\
 	.stream = {					\
 		.type = USB_ISOC,			\
@@ -788,6 +790,7 @@
 	}
 
 #define MXL111SF_EP6_BULK_STREAMING_CONFIG		\
+	.size_of_priv = sizeof(struct mxl111sf_adap_state), \
 	.streaming_ctrl = mxl111sf_ep6_streaming_ctrl,	\
 	.stream = {					\
 		.type = USB_BULK,			\
@@ -802,6 +805,7 @@
 
 /* FIXME */
 #define MXL111SF_EP6_ISOC_STREAMING_CONFIG		\
+	.size_of_priv = sizeof(struct mxl111sf_adap_state), \
 	.streaming_ctrl = mxl111sf_ep6_streaming_ctrl,	\
 	.stream = {					\
 		.type = USB_ISOC,			\
@@ -839,8 +843,6 @@
 		.fe_ioctl_override = mxl111sf_fe_ioctl_override,
 		.num_frontends = 1,
 		.fe = {{
-			.size_of_priv     = sizeof(struct mxl111sf_adap_state),
-
 			.frontend_attach  = mxl111sf_attach_demod,
 			.tuner_attach     = mxl111sf_attach_tuner,
 
@@ -883,8 +885,6 @@
 		.fe_ioctl_override = mxl111sf_fe_ioctl_override,
 		.num_frontends = 1,
 		.fe = {{
-			.size_of_priv     = sizeof(struct mxl111sf_adap_state),
-
 			.frontend_attach  = mxl111sf_attach_demod,
 			.tuner_attach     = mxl111sf_attach_tuner,
 
@@ -927,16 +927,12 @@
 		.fe_ioctl_override = mxl111sf_fe_ioctl_override,
 		.num_frontends = 2,
 		.fe = {{
-			.size_of_priv     = sizeof(struct mxl111sf_adap_state),
-
 			.frontend_attach  = mxl111sf_lgdt3305_frontend_attach,
 			.tuner_attach     = mxl111sf_attach_tuner,
 
 			MXL111SF_EP6_BULK_STREAMING_CONFIG,
 		},
 		{
-			.size_of_priv     = sizeof(struct mxl111sf_adap_state),
-
 			.frontend_attach  = mxl111sf_attach_demod,
 			.tuner_attach     = mxl111sf_attach_tuner,
 
@@ -992,16 +988,12 @@
 		.fe_ioctl_override = mxl111sf_fe_ioctl_override,
 		.num_frontends = 2,
 		.fe = {{
-			.size_of_priv     = sizeof(struct mxl111sf_adap_state),
-
 			.frontend_attach  = mxl111sf_lgdt3305_frontend_attach,
 			.tuner_attach     = mxl111sf_attach_tuner,
 
 			MXL111SF_EP6_ISOC_STREAMING_CONFIG,
 		},
 		{
-			.size_of_priv     = sizeof(struct mxl111sf_adap_state),
-
 			.frontend_attach  = mxl111sf_attach_demod,
 			.tuner_attach     = mxl111sf_attach_tuner,
 
diff --git a/drivers/media/dvb/dvb-usb/ttusb2.c b/drivers/media/dvb/dvb-usb/ttusb2.c
index ea4eab8..bc50356 100644
--- a/drivers/media/dvb/dvb-usb/ttusb2.c
+++ b/drivers/media/dvb/dvb-usb/ttusb2.c
@@ -75,10 +75,18 @@
 		u8 *wbuf, int wlen, u8 *rbuf, int rlen)
 {
 	struct ttusb2_state *st = d->priv;
-	u8 s[wlen+4],r[64] = { 0 };
+	u8 *s, *r = NULL;
 	int ret = 0;
 
-	memset(s,0,wlen+4);
+	s = kzalloc(wlen+4, GFP_KERNEL);
+	if (!s)
+		return -ENOMEM;
+
+	r = kzalloc(64, GFP_KERNEL);
+	if (!r) {
+		kfree(s);
+		return -ENOMEM;
+	}
 
 	s[0] = 0xaa;
 	s[1] = ++st->id;
@@ -94,12 +102,17 @@
 		r[2] != cmd ||
 		(rlen > 0 && r[3] != rlen)) {
 		warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]);
+		kfree(s);
+		kfree(r);
 		return -EIO;
 	}
 
 	if (rlen > 0)
 		memcpy(rbuf, &r[4], rlen);
 
+	kfree(s);
+	kfree(r);
+
 	return 0;
 }
 
@@ -384,7 +397,7 @@
 
 		memcpy(&obuf[3], msg[i].buf, msg[i].len);
 
-		if (ttusb2_msg(d, CMD_I2C_XFER, obuf, msg[i].len+3, ibuf, obuf[2] + 3) < 0) {
+		if (ttusb2_msg(d, CMD_I2C_XFER, obuf, obuf[1]+3, ibuf, obuf[2] + 3) < 0) {
 			err("i2c transfer failed.");
 			break;
 		}
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
index 489ae82..9debf0f 100644
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -392,10 +392,11 @@
 			default:		c->operand[13] = 0x2; break;
 			}
 			switch (fdtv->fe.dtv_property_cache.rolloff) {
-			case ROLLOFF_AUTO:	c->operand[14] = 0x2; break;
 			case ROLLOFF_35:	c->operand[14] = 0x2; break;
 			case ROLLOFF_20:	c->operand[14] = 0x0; break;
 			case ROLLOFF_25:	c->operand[14] = 0x1; break;
+			case ROLLOFF_AUTO:
+			default:		c->operand[14] = 0x2; break;
 			/* case ROLLOFF_NONE:	c->operand[14] = 0xff; break; */
 			}
 			switch (fdtv->fe.dtv_property_cache.pilot) {
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c
index 345311c..f4276e4 100644
--- a/drivers/media/dvb/frontends/af9013.c
+++ b/drivers/media/dvb/frontends/af9013.c
@@ -303,7 +303,8 @@
 	return ret;
 }
 
-static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw)
+static int af9013_set_freq_ctrl(struct af9013_state *state,
+	struct dvb_frontend *fe)
 {
 	int ret;
 	u16 addr;
@@ -324,37 +325,13 @@
 			bfs_spec_inv = state->config.rf_spec_inv ? 1 : -1;
 		}
 
-		adc_freq       = state->config.adc_clock * 1000;
-		if_sample_freq = state->config.tuner_if * 1000;
+		adc_freq = state->config.adc_clock * 1000;
 
-		/* TDA18271 uses different sampling freq for every bw */
-		if (state->config.tuner == AF9013_TUNER_TDA18271) {
-			switch (bw) {
-			case BANDWIDTH_6_MHZ:
-				if_sample_freq = 3300000; /* 3.3 MHz */
-				break;
-			case BANDWIDTH_7_MHZ:
-				if_sample_freq = 3500000; /* 3.5 MHz */
-				break;
-			case BANDWIDTH_8_MHZ:
-			default:
-				if_sample_freq = 4000000; /* 4.0 MHz */
-				break;
-			}
-		} else if (state->config.tuner == AF9013_TUNER_TDA18218) {
-			switch (bw) {
-			case BANDWIDTH_6_MHZ:
-				if_sample_freq = 3000000; /* 3 MHz */
-				break;
-			case BANDWIDTH_7_MHZ:
-				if_sample_freq = 3500000; /* 3.5 MHz */
-				break;
-			case BANDWIDTH_8_MHZ:
-			default:
-				if_sample_freq = 4000000; /* 4 MHz */
-				break;
-			}
-		}
+		/* get used IF frequency */
+		if (fe->ops.tuner_ops.get_if_frequency)
+			fe->ops.tuner_ops.get_if_frequency(fe, &if_sample_freq);
+		else
+			if_sample_freq = state->config.tuner_if * 1000;
 
 		while (if_sample_freq > (adc_freq / 2))
 			if_sample_freq = if_sample_freq - adc_freq;
@@ -639,7 +616,7 @@
 		goto error;
 
 	/* program frequency control */
-	ret = af9013_set_freq_ctrl(state, params->u.ofdm.bandwidth);
+	ret = af9013_set_freq_ctrl(state, fe);
 	if (ret)
 		goto error;
 
diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c
index 1d57294..5c0d398 100644
--- a/drivers/media/dvb/frontends/au8522_dig.c
+++ b/drivers/media/dvb/frontends/au8522_dig.c
@@ -862,7 +862,36 @@
 static int au8522_read_signal_strength(struct dvb_frontend *fe,
 				       u16 *signal_strength)
 {
-	return au8522_read_snr(fe, signal_strength);
+	/* borrowed from lgdt330x.c
+	 *
+	 * Calculate strength from SNR up to 35dB
+	 * Even though the SNR can go higher than 35dB,
+	 * there is some comfort factor in having a range of
+	 * strong signals that can show at 100%
+	 */
+	u16 snr;
+	u32 tmp;
+	int ret = au8522_read_snr(fe, &snr);
+
+	*signal_strength = 0;
+
+	if (0 == ret) {
+		/* The following calculation method was chosen
+		 * purely for the sake of code re-use from the
+		 * other demod drivers that use this method */
+
+		/* Convert from SNR in dB * 10 to 8.24 fixed-point */
+		tmp = (snr * ((1 << 24) / 10));
+
+		/* Convert from 8.24 fixed-point to
+		 * scale the range 0 - 35*2^24 into 0 - 65535*/
+		if (tmp >= 8960 * 0x10000)
+			*signal_strength = 0xffff;
+		else
+			*signal_strength = tmp / 8960;
+	}
+
+	return ret;
 }
 
 static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
diff --git a/drivers/media/dvb/frontends/cxd2820r.h b/drivers/media/dvb/frontends/cxd2820r.h
index 03cab7b..cf0f546 100644
--- a/drivers/media/dvb/frontends/cxd2820r.h
+++ b/drivers/media/dvb/frontends/cxd2820r.h
@@ -63,19 +63,6 @@
 	 */
 	bool spec_inv;
 
-	/* IFs for all used modes.
-	 * Default: none, must set
-	 * Values: <kHz>
-	 */
-	u16 if_dvbt_6;
-	u16 if_dvbt_7;
-	u16 if_dvbt_8;
-	u16 if_dvbt2_5;
-	u16 if_dvbt2_6;
-	u16 if_dvbt2_7;
-	u16 if_dvbt2_8;
-	u16 if_dvbc;
-
 	/* GPIOs for all used modes.
 	 * Default: none, disabled
 	 * Values: <see above>
diff --git a/drivers/media/dvb/frontends/cxd2820r_c.c b/drivers/media/dvb/frontends/cxd2820r_c.c
index b85f501..c412877 100644
--- a/drivers/media/dvb/frontends/cxd2820r_c.c
+++ b/drivers/media/dvb/frontends/cxd2820r_c.c
@@ -28,6 +28,7 @@
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	int ret, i;
 	u8 buf[2];
+	u32 if_freq;
 	u16 if_ctl;
 	u64 num;
 	struct reg_val_mask tab[] = {
@@ -70,7 +71,17 @@
 	priv->delivery_system = SYS_DVBC_ANNEX_AC;
 	priv->ber_running = 0; /* tune stops BER counter */
 
-	num = priv->cfg.if_dvbc;
+	/* program IF frequency */
+	if (fe->ops.tuner_ops.get_if_frequency) {
+		ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
+		if (ret)
+			goto error;
+	} else
+		if_freq = 0;
+
+	dbg("%s: if_freq=%d", __func__, if_freq);
+
+	num = if_freq / 1000; /* Hz => kHz */
 	num *= 0x4000;
 	if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
 	buf[0] = (if_ctl >> 8) & 0x3f;
diff --git a/drivers/media/dvb/frontends/cxd2820r_t.c b/drivers/media/dvb/frontends/cxd2820r_t.c
index a04f9c8..b1450ac 100644
--- a/drivers/media/dvb/frontends/cxd2820r_t.c
+++ b/drivers/media/dvb/frontends/cxd2820r_t.c
@@ -26,8 +26,8 @@
 {
 	struct cxd2820r_priv *priv = fe->demodulator_priv;
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-	int ret, i;
-	u32 if_khz, if_ctl;
+	int ret, i, bw_i;
+	u32 if_freq, if_ctl;
 	u64 num;
 	u8 buf[3], bw_param;
 	u8 bw_params1[][5] = {
@@ -57,6 +57,23 @@
 
 	dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz);
 
+	switch (c->bandwidth_hz) {
+	case 6000000:
+		bw_i = 0;
+		bw_param = 2;
+		break;
+	case 7000000:
+		bw_i = 1;
+		bw_param = 1;
+		break;
+	case 8000000:
+		bw_i = 2;
+		bw_param = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
 	/* update GPIOs */
 	ret = cxd2820r_gpio(fe);
 	if (ret)
@@ -78,27 +95,17 @@
 	priv->delivery_system = SYS_DVBT;
 	priv->ber_running = 0; /* tune stops BER counter */
 
-	switch (c->bandwidth_hz) {
-	case 6000000:
-		if_khz = priv->cfg.if_dvbt_6;
-		i = 0;
-		bw_param = 2;
-		break;
-	case 7000000:
-		if_khz = priv->cfg.if_dvbt_7;
-		i = 1;
-		bw_param = 1;
-		break;
-	case 8000000:
-		if_khz = priv->cfg.if_dvbt_8;
-		i = 2;
-		bw_param = 0;
-		break;
-	default:
-		return -EINVAL;
-	}
+	/* program IF frequency */
+	if (fe->ops.tuner_ops.get_if_frequency) {
+		ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
+		if (ret)
+			goto error;
+	} else
+		if_freq = 0;
 
-	num = if_khz;
+	dbg("%s: if_freq=%d", __func__, if_freq);
+
+	num = if_freq / 1000; /* Hz => kHz */
 	num *= 0x1000000;
 	if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
 	buf[0] = ((if_ctl >> 16) & 0xff);
@@ -109,7 +116,7 @@
 	if (ret)
 		goto error;
 
-	ret = cxd2820r_wr_regs(priv, 0x0009f, bw_params1[i], 5);
+	ret = cxd2820r_wr_regs(priv, 0x0009f, bw_params1[bw_i], 5);
 	if (ret)
 		goto error;
 
@@ -117,7 +124,7 @@
 	if (ret)
 		goto error;
 
-	ret = cxd2820r_wr_regs(priv, 0x000d9, bw_params2[i], 2);
+	ret = cxd2820r_wr_regs(priv, 0x000d9, bw_params2[bw_i], 2);
 	if (ret)
 		goto error;
 
diff --git a/drivers/media/dvb/frontends/cxd2820r_t2.c b/drivers/media/dvb/frontends/cxd2820r_t2.c
index 6548588..e21fc97 100644
--- a/drivers/media/dvb/frontends/cxd2820r_t2.c
+++ b/drivers/media/dvb/frontends/cxd2820r_t2.c
@@ -26,8 +26,8 @@
 {
 	struct cxd2820r_priv *priv = fe->demodulator_priv;
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-	int ret, i;
-	u32 if_khz, if_ctl;
+	int ret, i, bw_i;
+	u32 if_freq, if_ctl;
 	u64 num;
 	u8 buf[3], bw_param;
 	u8 bw_params1[][5] = {
@@ -71,6 +71,27 @@
 
 	dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz);
 
+	switch (c->bandwidth_hz) {
+	case 5000000:
+		bw_i = 0;
+		bw_param = 3;
+		break;
+	case 6000000:
+		bw_i = 1;
+		bw_param = 2;
+		break;
+	case 7000000:
+		bw_i = 2;
+		bw_param = 1;
+		break;
+	case 8000000:
+		bw_i = 3;
+		bw_param = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
 	/* update GPIOs */
 	ret = cxd2820r_gpio(fe);
 	if (ret)
@@ -91,32 +112,17 @@
 
 	priv->delivery_system = SYS_DVBT2;
 
-	switch (c->bandwidth_hz) {
-	case 5000000:
-		if_khz = priv->cfg.if_dvbt2_5;
-		i = 0;
-		bw_param = 3;
-		break;
-	case 6000000:
-		if_khz = priv->cfg.if_dvbt2_6;
-		i = 1;
-		bw_param = 2;
-		break;
-	case 7000000:
-		if_khz = priv->cfg.if_dvbt2_7;
-		i = 2;
-		bw_param = 1;
-		break;
-	case 8000000:
-		if_khz = priv->cfg.if_dvbt2_8;
-		i = 3;
-		bw_param = 0;
-		break;
-	default:
-		return -EINVAL;
-	}
+	/* program IF frequency */
+	if (fe->ops.tuner_ops.get_if_frequency) {
+		ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
+		if (ret)
+			goto error;
+	} else
+		if_freq = 0;
 
-	num = if_khz;
+	dbg("%s: if_freq=%d", __func__, if_freq);
+
+	num = if_freq / 1000; /* Hz => kHz */
 	num *= 0x1000000;
 	if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
 	buf[0] = ((if_ctl >> 16) & 0xff);
@@ -127,7 +133,7 @@
 	if (ret)
 		goto error;
 
-	ret = cxd2820r_wr_regs(priv, 0x0209f, bw_params1[i], 5);
+	ret = cxd2820r_wr_regs(priv, 0x0209f, bw_params1[bw_i], 5);
 	if (ret)
 		goto error;
 
diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c
index b174d1c..2b30ab2 100644
--- a/drivers/media/dvb/frontends/dib0090.c
+++ b/drivers/media/dvb/frontends/dib0090.c
@@ -717,6 +717,34 @@
 	(0 << 10) | 109,	/* RF_RAMP4, LNA 4 */
 };
 
+static const uint16_t rf_ramp_pwm_cband_7090e_sensitivity[] = {
+	186,
+	40,
+	746,
+	(10 << 10) | 345,
+	(0  << 10) | 746,
+	(0 << 10) | 0,
+	(0  << 10) | 0,
+	(28 << 10) | 200,
+	(0  << 10) | 345,
+	(20 << 10) | 0,
+	(0  << 10) | 200,
+};
+
+static const uint16_t rf_ramp_pwm_cband_7090e_aci[] = {
+	86,
+	40,
+	345,
+	(0 << 10) | 0,
+	(0 << 10) | 0,
+	(0 << 10) | 0,
+	(0 << 10) | 0,
+	(28 << 10) | 200,
+	(0  << 10) | 345,
+	(20 << 10) | 0,
+	(0  << 10) | 200,
+};
+
 static const u16 rf_ramp_pwm_cband_8090[] = {
 	345,			/* max RF gain in 10th of dB */
 	29,			/* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
@@ -1076,8 +1104,16 @@
 				dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
 				if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
 					dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_8090);
-				else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
-					dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090);
+				else if (state->identity.version == SOC_7090_P1G_11R1
+						|| state->identity.version == SOC_7090_P1G_21R1) {
+					if (state->config->is_dib7090e) {
+						if (state->rf_ramp == NULL)
+							dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090e_sensitivity);
+						else
+							dib0090_set_rframp_pwm(state, state->rf_ramp);
+					} else
+						dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090);
+				}
 			} else {
 				dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband);
 				dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
@@ -1112,13 +1148,21 @@
 		else
 			dib0090_write_reg(state, 0x32, (0 << 11));
 
-		dib0090_write_reg(state, 0x04, 0x01);
+		dib0090_write_reg(state, 0x04, 0x03);
 		dib0090_write_reg(state, 0x39, (1 << 10));
 	}
 }
 
 EXPORT_SYMBOL(dib0090_pwm_gain_reset);
 
+void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+	if (DC_servo_cutoff < 4)
+		dib0090_write_reg(state, 0x04, DC_servo_cutoff);
+}
+EXPORT_SYMBOL(dib0090_set_dc_servo);
+
 static u32 dib0090_get_slow_adc_val(struct dib0090_state *state)
 {
 	u16 adc_val = dib0090_read_reg(state, 0x1d);
@@ -1305,7 +1349,7 @@
 
 EXPORT_SYMBOL(dib0090_get_current_gain);
 
-u16 dib0090_get_wbd_offset(struct dvb_frontend *fe)
+u16 dib0090_get_wbd_target(struct dvb_frontend *fe)
 {
 	struct dib0090_state *state = fe->tuner_priv;
 	u32 f_MHz = state->fe->dtv_property_cache.frequency / 1000000;
@@ -1342,9 +1386,57 @@
 
 	return state->wbd_offset + wbd_tcold;
 }
+EXPORT_SYMBOL(dib0090_get_wbd_target);
 
+u16 dib0090_get_wbd_offset(struct dvb_frontend *fe)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+	return state->wbd_offset;
+}
 EXPORT_SYMBOL(dib0090_get_wbd_offset);
 
+int dib0090_set_switch(struct dvb_frontend *fe, u8 sw1, u8 sw2, u8 sw3)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+
+	dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xfff8)
+			| ((sw3 & 1) << 2) | ((sw2 & 1) << 1) | (sw1 & 1));
+
+	return 0;
+}
+EXPORT_SYMBOL(dib0090_set_switch);
+
+int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+
+	dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x7fff)
+			| ((onoff & 1) << 15));
+	return 0;
+}
+EXPORT_SYMBOL(dib0090_set_vga);
+
+int dib0090_update_rframp_7090(struct dvb_frontend *fe, u8 cfg_sensitivity)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+
+	if ((!state->identity.p1g) || (!state->identity.in_soc)
+			|| ((state->identity.version != SOC_7090_P1G_21R1)
+				&& (state->identity.version != SOC_7090_P1G_11R1))) {
+		dprintk("%s() function can only be used for dib7090P", __func__);
+		return -ENODEV;
+	}
+
+	if (cfg_sensitivity)
+		state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_sensitivity;
+	else
+		state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_aci;
+	dib0090_pwm_gain_reset(fe);
+
+	return 0;
+}
+EXPORT_SYMBOL(dib0090_update_rframp_7090);
+
 static const u16 dib0090_defaults[] = {
 
 	25, 0x01,
@@ -1430,7 +1522,7 @@
 #define POLY_MIN      (u8)  0
 #define POLY_MAX      (u8)  8
 
-void dib0090_set_EFUSE(struct dib0090_state *state)
+static void dib0090_set_EFUSE(struct dib0090_state *state)
 {
 	u8 c, h, n;
 	u16 e2, e4;
@@ -1505,7 +1597,10 @@
 		dib0090_set_EFUSE(state);
 
 	/* Congigure in function of the crystal */
-	if (state->config->io.clock_khz >= 24000)
+	if (state->config->force_crystal_mode != 0)
+		dib0090_write_reg(state, 0x14,
+				state->config->force_crystal_mode & 3);
+	else if (state->config->io.clock_khz >= 24000)
 		dib0090_write_reg(state, 0x14, 1);
 	else
 		dib0090_write_reg(state, 0x14, 2);
@@ -1951,6 +2046,52 @@
 #endif
 };
 
+static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_sensitivity[] = {
+#ifdef CONFIG_BAND_CBAND
+	{ 300000,  0 ,  3,  0x8105, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
+	{ 380000,  0 ,  10, 0x810F, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
+	{ 600000,  0 ,  10, 0x815E, 0x280, 0x2d12, 0xb84e, EN_CAB },
+	{ 660000,  0 ,  5,  0x85E3, 0x280, 0x2d12, 0xb84e, EN_CAB },
+	{ 720000,  0 ,  5,  0x852E, 0x280, 0x2d12, 0xb84e, EN_CAB },
+	{ 860000,  0 ,  4,  0x85E5, 0x280, 0x2d12, 0xb84e, EN_CAB },
+#endif
+};
+
+int dib0090_update_tuning_table_7090(struct dvb_frontend *fe,
+		u8 cfg_sensitivity)
+{
+	struct dib0090_state *state = fe->tuner_priv;
+	const struct dib0090_tuning *tune =
+		dib0090_tuning_table_cband_7090e_sensitivity;
+	const struct dib0090_tuning dib0090_tuning_table_cband_7090e_aci[] = {
+		{ 300000,  0 ,  3,  0x8165, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
+		{ 650000,  0 ,  4,  0x815B, 0x280, 0x2d12, 0xb84e, EN_CAB },
+		{ 860000,  0 ,  5,  0x84EF, 0x280, 0x2d12, 0xb84e, EN_CAB },
+	};
+
+	if ((!state->identity.p1g) || (!state->identity.in_soc)
+			|| ((state->identity.version != SOC_7090_P1G_21R1)
+				&& (state->identity.version != SOC_7090_P1G_11R1))) {
+		dprintk("%s() function can only be used for dib7090", __func__);
+		return -ENODEV;
+	}
+
+	if (cfg_sensitivity)
+		tune = dib0090_tuning_table_cband_7090e_sensitivity;
+	else
+		tune = dib0090_tuning_table_cband_7090e_aci;
+
+	while (state->rf_request > tune->max_freq)
+		tune++;
+
+	dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x8000)
+			| (tune->lna_bias & 0x7fff));
+	dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xf83f)
+			| ((tune->lna_tune << 6) & 0x07c0));
+	return 0;
+}
+EXPORT_SYMBOL(dib0090_update_tuning_table_7090);
+
 static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state)
 {
 	int ret = 0;
@@ -2199,12 +2340,18 @@
 					if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF
 							|| state->current_band & BAND_UHF) {
 						state->current_band = BAND_CBAND;
-						tune = dib0090_tuning_table_cband_7090;
+						if (state->config->is_dib7090e)
+							tune = dib0090_tuning_table_cband_7090e_sensitivity;
+						else
+							tune = dib0090_tuning_table_cband_7090;
 					}
 				} else {	/* Use the CBAND input for all band under UHF */
 					if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) {
 						state->current_band = BAND_CBAND;
-						tune = dib0090_tuning_table_cband_7090;
+						if (state->config->is_dib7090e)
+							tune = dib0090_tuning_table_cband_7090e_sensitivity;
+						else
+							tune = dib0090_tuning_table_cband_7090;
 					}
 				}
 			} else
diff --git a/drivers/media/dvb/frontends/dib0090.h b/drivers/media/dvb/frontends/dib0090.h
index 13d8524..781dc49 100644
--- a/drivers/media/dvb/frontends/dib0090.h
+++ b/drivers/media/dvb/frontends/dib0090.h
@@ -71,6 +71,8 @@
 	u8 fref_clock_ratio;
 	u16 force_cband_input;
 	struct dib0090_wbd_slope *wbd;
+	u8 is_dib7090e;
+	u8 force_crystal_mode;
 };
 
 #if defined(CONFIG_DVB_TUNER_DIB0090) || (defined(CONFIG_DVB_TUNER_DIB0090_MODULE) && defined(MODULE))
@@ -78,13 +80,21 @@
 extern struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
 extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast);
 extern void dib0090_pwm_gain_reset(struct dvb_frontend *fe);
-extern u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner);
+extern u16 dib0090_get_wbd_target(struct dvb_frontend *tuner);
+extern u16 dib0090_get_wbd_offset(struct dvb_frontend *fe);
 extern int dib0090_gain_control(struct dvb_frontend *fe);
 extern enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe);
 extern int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state);
 extern void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt);
+extern void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff);
+extern int dib0090_set_switch(struct dvb_frontend *fe, u8 sw1, u8 sw2, u8 sw3);
+extern int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff);
+extern int dib0090_update_rframp_7090(struct dvb_frontend *fe,
+		u8 cfg_sensitivity);
+extern int dib0090_update_tuning_table_7090(struct dvb_frontend *fe,
+		u8 cfg_sensitivity);
 #else
-static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0090_config *config)
+static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
@@ -106,7 +116,13 @@
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 }
 
-static inline u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner)
+static inline u16 dib0090_get_wbd_target(struct dvb_frontend *tuner)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return 0;
+}
+
+static inline u16 dib0090_get_wbd_offset(struct dvb_frontend *fe)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return 0;
@@ -134,6 +150,38 @@
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 }
+
+static inline void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+}
+
+static inline int dib0090_set_switch(struct dvb_frontend *fe,
+		u8 sw1, u8 sw2, u8 sw3)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
+
+static inline int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
+
+static inline int dib0090_update_rframp_7090(struct dvb_frontend *fe,
+		u8 cfg_sensitivity)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
+
+static inline int dib0090_update_tuning_table_7090(struct dvb_frontend *fe,
+		u8 cfg_sensitivity)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
 #endif
 
 #endif
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index ce8534f..b5f3fb4 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -70,6 +70,8 @@
 	u8 i2c_write_buffer[4];
 	u8 i2c_read_buffer[2];
 	struct mutex i2c_buffer_lock;
+
+	u8 input_mode_mpeg;
 };
 
 enum dib7000p_power_mode {
@@ -78,8 +80,11 @@
 	DIB7000P_POWER_INTERFACE_ONLY,
 };
 
+/* dib7090 specific fonctions */
 static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode);
 static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
+static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode);
+static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode);
 
 static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
 {
@@ -276,17 +281,23 @@
 	dib7000p_write_word(state, 774, reg_774);
 	dib7000p_write_word(state, 775, reg_775);
 	dib7000p_write_word(state, 776, reg_776);
-	dib7000p_write_word(state, 899, reg_899);
 	dib7000p_write_word(state, 1280, reg_1280);
+	if (state->version != SOC7090)
+		dib7000p_write_word(state, 899, reg_899);
 
 	return 0;
 }
 
 static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no)
 {
-	u16 reg_908 = dib7000p_read_word(state, 908), reg_909 = dib7000p_read_word(state, 909);
+	u16 reg_908 = 0, reg_909 = 0;
 	u16 reg;
 
+	if (state->version != SOC7090) {
+		reg_908 = dib7000p_read_word(state, 908);
+		reg_909 = dib7000p_read_word(state, 909);
+	}
+
 	switch (no) {
 	case DIBX000_SLOW_ADC_ON:
 		if (state->version == SOC7090) {
@@ -342,8 +353,10 @@
 	reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4;
 	reg_908 |= (state->cfg.enable_current_mirror & 1) << 7;
 
-	dib7000p_write_word(state, 908, reg_908);
-	dib7000p_write_word(state, 909, reg_909);
+	if (state->version != SOC7090) {
+		dib7000p_write_word(state, 908, reg_908);
+		dib7000p_write_word(state, 909, reg_909);
+	}
 }
 
 static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
@@ -398,6 +411,24 @@
 }
 EXPORT_SYMBOL(dib7000p_set_wbd_ref);
 
+int dib7000p_get_agc_values(struct dvb_frontend *fe,
+		u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd)
+{
+	struct dib7000p_state *state = fe->demodulator_priv;
+
+	if (agc_global != NULL)
+		*agc_global = dib7000p_read_word(state, 394);
+	if (agc1 != NULL)
+		*agc1 = dib7000p_read_word(state, 392);
+	if (agc2 != NULL)
+		*agc2 = dib7000p_read_word(state, 393);
+	if (wbd != NULL)
+		*wbd = dib7000p_read_word(state, 397);
+
+	return 0;
+}
+EXPORT_SYMBOL(dib7000p_get_agc_values);
+
 static void dib7000p_reset_pll(struct dib7000p_state *state)
 {
 	struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
@@ -519,7 +550,7 @@
 	// auto search configuration
 	3, 2,
 	0x0004,
-	0x1000,
+	(1<<3)|(1<<11)|(1<<12)|(1<<13),
 	0x0814,			/* Equal Lock */
 
 	12, 6,
@@ -595,13 +626,6 @@
 	1, 235,
 	0x0062,
 
-	2, 901,
-	0x0006,
-	(3 << 10) | (1 << 6),
-
-	1, 905,
-	0x2c8e,
-
 	0,
 };
 
@@ -618,15 +642,18 @@
 	dib7000p_write_word(state, 770, 0xffff);
 	dib7000p_write_word(state, 771, 0xffff);
 	dib7000p_write_word(state, 772, 0x001f);
-	dib7000p_write_word(state, 898, 0x0003);
 	dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3)));
 
 	dib7000p_write_word(state, 770, 0);
 	dib7000p_write_word(state, 771, 0);
 	dib7000p_write_word(state, 772, 0);
-	dib7000p_write_word(state, 898, 0);
 	dib7000p_write_word(state, 1280, 0);
 
+	if (state->version != SOC7090) {
+		dib7000p_write_word(state,  898, 0x0003);
+		dib7000p_write_word(state,  898, 0);
+	}
+
 	/* default */
 	dib7000p_reset_pll(state);
 
@@ -640,7 +667,7 @@
 		dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */
 		dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */
 		dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */
-		dib7000p_write_word(state, 273, (1<<6) | 30);
+		dib7000p_write_word(state, 273, (0<<6) | 30);
 	}
 	if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
 		dprintk("OUTPUT_MODE could not be reset.");
@@ -655,7 +682,7 @@
 	dib7000p_set_bandwidth(state, 8000);
 
 	if (state->version == SOC7090) {
-		dib7000p_write_word(state, 36, 0x5755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
+		dib7000p_write_word(state, 36, 0x0755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
 	} else {
 		if (state->cfg.tuner_is_baseband)
 			dib7000p_write_word(state, 36, 0x0755);
@@ -664,6 +691,11 @@
 	}
 
 	dib7000p_write_tab(state, dib7000p_defaults);
+	if (state->version != SOC7090) {
+		dib7000p_write_word(state, 901, 0x0006);
+		dib7000p_write_word(state, 902, (3 << 10) | (1 << 6));
+		dib7000p_write_word(state, 905, 0x2c8e);
+	}
 
 	dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
 
@@ -1080,9 +1112,12 @@
 	dib7000p_set_channel(state, &schan, 7);
 
 	factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);
-	if (factor >= 5000)
-		factor = 1;
-	else
+	if (factor >= 5000) {
+		if (state->version == SOC7090)
+			factor = 2;
+		else
+			factor = 1;
+	} else
 		factor = 6;
 
 	value = 30 * internal * factor;
@@ -1323,7 +1358,7 @@
 {
 	struct dib7000p_state *state = demod->demodulator_priv;
 	if (state->version == SOC7090)
-		return dib7090_set_output_mode(demod, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
+		return dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
 	return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
 }
 
@@ -1445,10 +1480,9 @@
 	struct dib7000p_state *state = fe->demodulator_priv;
 	int time, ret;
 
-	if (state->version == SOC7090) {
+	if (state->version == SOC7090)
 		dib7090_set_diversity_in(fe, 0);
-		dib7090_set_output_mode(fe, OUTMODE_HIGH_Z);
-	} else
+	else
 		dib7000p_set_output_mode(state, OUTMODE_HIGH_Z);
 
 	/* maybe the parameter has been changed */
@@ -1485,9 +1519,13 @@
 	ret = dib7000p_tune(fe, fep);
 
 	/* make this a config parameter */
-	if (state->version == SOC7090)
+	if (state->version == SOC7090) {
 		dib7090_set_output_mode(fe, state->cfg.output_mode);
-	else
+		if (state->cfg.enMpegOutput == 0) {
+			dib7090_setDibTxMux(state, MPEG_ON_DIBTX);
+			dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
+		}
+	} else
 		dib7000p_set_output_mode(state, state->cfg.output_mode);
 
 	return ret;
@@ -1831,7 +1869,8 @@
 	return num;
 }
 
-int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num, u16 apb_address)
+static int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap,
+		struct i2c_msg msg[], int num, u16 apb_address)
 {
 	struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
 	u16 word;
@@ -1933,10 +1972,10 @@
 		apb_address = 915;
 		break;
 	case 0x27:
-		apb_address = 916;
+		apb_address = 917;
 		break;
 	case 0x28:
-		apb_address = 917;
+		apb_address = 916;
 		break;
 	case 0x1d:
 		i = ((dib7000p_read_word(state, 72) >> 12) & 0x3);
@@ -2031,12 +2070,7 @@
 
 static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize)
 {
-	u8 index_buf;
-	u16 rx_copy_buf[22];
-
 	dprintk("Configure DibStream Tx");
-	for (index_buf = 0; index_buf < 22; index_buf++)
-		rx_copy_buf[index_buf] = dib7000p_read_word(state, 1536+index_buf);
 
 	dib7000p_write_word(state, 1615, 1);
 	dib7000p_write_word(state, 1603, P_Kin);
@@ -2048,9 +2082,6 @@
 	dib7000p_write_word(state, 1612, syncSize);
 	dib7000p_write_word(state, 1615, 0);
 
-	for (index_buf = 0; index_buf < 22; index_buf++)
-		dib7000p_write_word(state, 1536+index_buf, rx_copy_buf[index_buf]);
-
 	return 0;
 }
 
@@ -2077,109 +2108,121 @@
 	return 0;
 }
 
-static int dib7090_enDivOnHostBus(struct dib7000p_state *state)
+static void dib7090_enMpegMux(struct dib7000p_state *state, int onoff)
 {
-	u16 reg;
+	u16 reg_1287 = dib7000p_read_word(state, 1287);
 
-	dprintk("Enable Diversity on host bus");
-	reg = (1 << 8) | (1 << 5);
-	dib7000p_write_word(state, 1288, reg);
+	switch (onoff) {
+	case 1:
+			reg_1287 &= ~(1<<7);
+			break;
+	case 0:
+			reg_1287 |= (1<<7);
+			break;
+	}
 
-	return dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
+	dib7000p_write_word(state, 1287, reg_1287);
 }
 
-static int dib7090_enAdcOnHostBus(struct dib7000p_state *state)
+static void dib7090_configMpegMux(struct dib7000p_state *state,
+		u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
 {
-	u16 reg;
-
-	dprintk("Enable ADC on host bus");
-	reg = (1 << 7) | (1 << 5);
-	dib7000p_write_word(state, 1288, reg);
-
-	return dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
-}
-
-static int dib7090_enMpegOnHostBus(struct dib7000p_state *state)
-{
-	u16 reg;
-
-	dprintk("Enable Mpeg on host bus");
-	reg = (1 << 9) | (1 << 5);
-	dib7000p_write_word(state, 1288, reg);
-
-	return dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
-}
-
-static int dib7090_enMpegInput(struct dib7000p_state *state)
-{
-	dprintk("Enable Mpeg input");
-	return dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0);	/*outputRate = 8 */
-}
-
-static int dib7090_enMpegMux(struct dib7000p_state *state, u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
-{
-	u16 reg = (1 << 7) | ((pulseWidth & 0x1f) << 2) | ((enSerialMode & 0x1) << 1) | (enSerialClkDiv2 & 0x1);
-
 	dprintk("Enable Mpeg mux");
-	dib7000p_write_word(state, 1287, reg);
 
-	reg &= ~(1 << 7);
-	dib7000p_write_word(state, 1287, reg);
+	dib7090_enMpegMux(state, 0);
 
-	reg = (1 << 4);
-	dib7000p_write_word(state, 1288, reg);
+	/* If the input mode is MPEG do not divide the serial clock */
+	if ((enSerialMode == 1) && (state->input_mode_mpeg == 1))
+		enSerialClkDiv2 = 0;
 
-	return 0;
+	dib7000p_write_word(state, 1287, ((pulseWidth & 0x1f) << 2)
+			| ((enSerialMode & 0x1) << 1)
+			| (enSerialClkDiv2 & 0x1));
+
+	dib7090_enMpegMux(state, 1);
 }
 
-static int dib7090_disableMpegMux(struct dib7000p_state *state)
+static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode)
 {
-	u16 reg;
-
-	dprintk("Disable Mpeg mux");
-	dib7000p_write_word(state, 1288, 0);
-
-	reg = dib7000p_read_word(state, 1287);
-	reg &= ~(1 << 7);
-	dib7000p_write_word(state, 1287, reg);
-
-	return 0;
-}
-
-static int dib7090_set_input_mode(struct dvb_frontend *fe, int mode)
-{
-	struct dib7000p_state *state = fe->demodulator_priv;
+	u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 7);
 
 	switch (mode) {
-	case INPUT_MODE_DIVERSITY:
-			dprintk("Enable diversity INPUT");
-			dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
+	case MPEG_ON_DIBTX:
+			dprintk("SET MPEG ON DIBSTREAM TX");
+			dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
+			reg_1288 |= (1<<9);
 			break;
-	case INPUT_MODE_MPEG:
-			dprintk("Enable Mpeg INPUT");
-			dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */
+	case DIV_ON_DIBTX:
+			dprintk("SET DIV_OUT ON DIBSTREAM TX");
+			dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
+			reg_1288 |= (1<<8);
 			break;
-	case INPUT_MODE_OFF:
+	case ADC_ON_DIBTX:
+			dprintk("SET ADC_OUT ON DIBSTREAM TX");
+			dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
+			reg_1288 |= (1<<7);
+			break;
 	default:
-			dprintk("Disable INPUT");
-			dib7090_cfg_DibRx(state, 0, 0, 0, 0, 0, 0, 0);
 			break;
 	}
-	return 0;
+	dib7000p_write_word(state, 1288, reg_1288);
 }
 
-static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
+static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode)
 {
+	u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 4);
+
+	switch (mode) {
+	case DEMOUT_ON_HOSTBUS:
+			dprintk("SET DEM OUT OLD INTERF ON HOST BUS");
+			dib7090_enMpegMux(state, 0);
+			reg_1288 |= (1<<6);
+			break;
+	case DIBTX_ON_HOSTBUS:
+			dprintk("SET DIBSTREAM TX ON HOST BUS");
+			dib7090_enMpegMux(state, 0);
+			reg_1288 |= (1<<5);
+			break;
+	case MPEG_ON_HOSTBUS:
+			dprintk("SET MPEG MUX ON HOST BUS");
+			reg_1288 |= (1<<4);
+			break;
+	default:
+			break;
+	}
+	dib7000p_write_word(state, 1288, reg_1288);
+}
+
+int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
+{
+	struct dib7000p_state *state = fe->demodulator_priv;
+	u16 reg_1287;
+
 	switch (onoff) {
-	case 0:		/* only use the internal way - not the diversity input */
-		dib7090_set_input_mode(fe, INPUT_MODE_MPEG);
-		break;
-	case 1:		/* both ways */
-	case 2:		/* only the diversity input */
-		dib7090_set_input_mode(fe, INPUT_MODE_DIVERSITY);
-		break;
+	case 0: /* only use the internal way - not the diversity input */
+			dprintk("%s mode OFF : by default Enable Mpeg INPUT", __func__);
+			dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0);
+
+			/* Do not divide the serial clock of MPEG MUX */
+			/* in SERIAL MODE in case input mode MPEG is used */
+			reg_1287 = dib7000p_read_word(state, 1287);
+			/* enSerialClkDiv2 == 1 ? */
+			if ((reg_1287 & 0x1) == 1) {
+				/* force enSerialClkDiv2 = 0 */
+				reg_1287 &= ~0x1;
+				dib7000p_write_word(state, 1287, reg_1287);
+			}
+			state->input_mode_mpeg = 1;
+			break;
+	case 1: /* both ways */
+	case 2: /* only the diversity input */
+			dprintk("%s ON : Enable diversity INPUT", __func__);
+			dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
+			state->input_mode_mpeg = 0;
+			break;
 	}
 
+	dib7000p_set_diversity_in(&state->demod, onoff);
 	return 0;
 }
 
@@ -2204,69 +2247,63 @@
 
 	case OUTMODE_MPEG2_SERIAL:
 		if (prefer_mpeg_mux_use) {
-			dprintk("Sip 7090P setting output mode TS_SERIAL using Mpeg Mux");
-			dib7090_enMpegOnHostBus(state);
-			dib7090_enMpegInput(state);
-			if (state->cfg.enMpegOutput == 1)
-				dib7090_enMpegMux(state, 3, 1, 1);
-
-		} else {	/* Use Smooth block */
-			dprintk("Sip 7090P setting output mode TS_SERIAL using Smooth bloc");
-			dib7090_disableMpegMux(state);
-			dib7000p_write_word(state, 1288, (1 << 6));
-			outreg |= (2 << 6) | (0 << 1);
+			dprintk("setting output mode TS_SERIAL using Mpeg Mux");
+			dib7090_configMpegMux(state, 3, 1, 1);
+			dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS);
+		} else {/* Use Smooth block */
+			dprintk("setting output mode TS_SERIAL using Smooth bloc");
+			dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
+			outreg |= (2<<6) | (0 << 1);
 		}
 		break;
 
 	case OUTMODE_MPEG2_PAR_GATED_CLK:
 		if (prefer_mpeg_mux_use) {
-			dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
-			dib7090_enMpegOnHostBus(state);
-			dib7090_enMpegInput(state);
-			if (state->cfg.enMpegOutput == 1)
-				dib7090_enMpegMux(state, 2, 0, 0);
-		} else {	/* Use Smooth block */
-			dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Smooth block");
-			dib7090_disableMpegMux(state);
-			dib7000p_write_word(state, 1288, (1 << 6));
-			outreg |= (0 << 6);
+			dprintk("setting output mode TS_PARALLEL_GATED using Mpeg Mux");
+			dib7090_configMpegMux(state, 2, 0, 0);
+			dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS);
+		} else { /* Use Smooth block */
+			dprintk("setting output mode TS_PARALLEL_GATED using Smooth block");
+			dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
+			outreg |= (0<<6);
 		}
 		break;
 
 	case OUTMODE_MPEG2_PAR_CONT_CLK:	/* Using Smooth block only */
-		dprintk("Sip 7090P setting output mode TS_PARALLEL_CONT using Smooth block");
-		dib7090_disableMpegMux(state);
-		dib7000p_write_word(state, 1288, (1 << 6));
-		outreg |= (1 << 6);
+		dprintk("setting output mode TS_PARALLEL_CONT using Smooth block");
+		dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
+		outreg |= (1<<6);
 		break;
 
 	case OUTMODE_MPEG2_FIFO:	/* Using Smooth block because not supported by new Mpeg Mux bloc */
-		dprintk("Sip 7090P setting output mode TS_FIFO using Smooth block");
-		dib7090_disableMpegMux(state);
-		dib7000p_write_word(state, 1288, (1 << 6));
-		outreg |= (5 << 6);
+		dprintk("setting output mode TS_FIFO using Smooth block");
+		dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
+		outreg |= (5<<6);
 		smo_mode |= (3 << 1);
 		fifo_threshold = 512;
 		break;
 
 	case OUTMODE_DIVERSITY:
-		dprintk("Sip 7090P setting output mode MODE_DIVERSITY");
-		dib7090_disableMpegMux(state);
-		dib7090_enDivOnHostBus(state);
+		dprintk("setting output mode MODE_DIVERSITY");
+		dib7090_setDibTxMux(state, DIV_ON_DIBTX);
+		dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
 		break;
 
 	case OUTMODE_ANALOG_ADC:
-		dprintk("Sip 7090P setting output mode MODE_ANALOG_ADC");
-		dib7090_enAdcOnHostBus(state);
+		dprintk("setting output mode MODE_ANALOG_ADC");
+		dib7090_setDibTxMux(state, ADC_ON_DIBTX);
+		dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
 		break;
 	}
+	if (mode != OUTMODE_HIGH_Z)
+		outreg |= (1 << 10);
 
 	if (state->cfg.output_mpeg2_in_188_bytes)
 		smo_mode |= (1 << 5);
 
 	ret |= dib7000p_write_word(state, 235, smo_mode);
 	ret |= dib7000p_write_word(state, 236, fifo_threshold);	/* synchronous fread */
-	ret |= dib7000p_write_word(state, 1286, outreg | (1 << 10));	/* allways set Dout active = 1 !!! */
+	ret |= dib7000p_write_word(state, 1286, outreg);
 
 	return ret;
 }
@@ -2296,13 +2333,6 @@
 }
 EXPORT_SYMBOL(dib7090_tuner_sleep);
 
-int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
-{
-	dprintk("AGC restart callback: %d", restart);
-	return 0;
-}
-EXPORT_SYMBOL(dib7090_agc_restart);
-
 int dib7090_get_adc_power(struct dvb_frontend *fe)
 {
 	return dib7000p_get_adc_power(fe);
diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h
index 0179f94..b61b03a 100644
--- a/drivers/media/dvb/frontends/dib7000p.h
+++ b/drivers/media/dvb/frontends/dib7000p.h
@@ -56,11 +56,12 @@
 extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
 extern int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw);
 extern u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf);
-extern int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart);
 extern int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff);
 extern int dib7090_get_adc_power(struct dvb_frontend *fe);
 extern struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe);
 extern int dib7090_slave_reset(struct dvb_frontend *fe);
+extern int dib7000p_get_agc_values(struct dvb_frontend *fe,
+		u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd);
 #else
 static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
 {
@@ -122,12 +123,6 @@
 	return 0;
 }
 
-static inline int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
-{
-	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-	return -ENODEV;
-}
-
 static inline int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
@@ -151,6 +146,13 @@
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return -ENODEV;
 }
+
+static inline int dib7000p_get_agc_values(struct dvb_frontend *fe,
+		u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
 #endif
 
 #endif
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c
index fe284d5..b8da0c9 100644
--- a/drivers/media/dvb/frontends/dib8000.c
+++ b/drivers/media/dvb/frontends/dib8000.c
@@ -81,11 +81,15 @@
 	u8 i2c_write_buffer[4];
 	u8 i2c_read_buffer[2];
 	struct mutex i2c_buffer_lock;
+	u8 input_mode_mpeg;
+
+	u16 tuner_enable;
+	struct i2c_adapter dib8096p_tuner_adap;
 };
 
 enum dib8000_power_mode {
-	DIB8000M_POWER_ALL = 0,
-	DIB8000M_POWER_INTERFACE_ONLY,
+	DIB8000_POWER_ALL = 0,
+	DIB8000_POWER_INTERFACE_ONLY,
 };
 
 static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
@@ -428,20 +432,31 @@
 	/* by default everything is going to be powered off */
 	u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
 		reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3,
+		reg_1280;
+
+	if (state->revision != 0x8090)
 		reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
+	else
+		reg_1280 = (dib8000_read_word(state, 1280) & 0x707f) | 0x8f80;
 
 	/* now, depending on the requested mode, we power on */
 	switch (mode) {
 		/* power up everything in the demod */
-	case DIB8000M_POWER_ALL:
+	case DIB8000_POWER_ALL:
 		reg_774 = 0x0000;
 		reg_775 = 0x0000;
 		reg_776 = 0x0000;
 		reg_900 &= 0xfffc;
-		reg_1280 &= 0x00ff;
+		if (state->revision != 0x8090)
+			reg_1280 &= 0x00ff;
+		else
+			reg_1280 &= 0x707f;
 		break;
-	case DIB8000M_POWER_INTERFACE_ONLY:
-		reg_1280 &= 0x00ff;
+	case DIB8000_POWER_INTERFACE_ONLY:
+		if (state->revision != 0x8090)
+			reg_1280 &= 0x00ff;
+		else
+			reg_1280 &= 0xfa7b;
 		break;
 	}
 
@@ -453,19 +468,67 @@
 	dib8000_write_word(state, 1280, reg_1280);
 }
 
+static int dib8000_init_sdram(struct dib8000_state *state)
+{
+	u16 reg = 0;
+	dprintk("Init sdram");
+
+	reg = dib8000_read_word(state, 274)&0xfff0;
+	/* P_dintlv_delay_ram = 7 because of MobileSdram */
+	dib8000_write_word(state, 274, reg | 0x7);
+
+	dib8000_write_word(state, 1803, (7<<2));
+
+	reg = dib8000_read_word(state, 1280);
+	/* force restart P_restart_sdram */
+	dib8000_write_word(state, 1280,  reg | (1<<2));
+
+	/* release restart P_restart_sdram */
+	dib8000_write_word(state, 1280,  reg);
+
+	return 0;
+}
+
 static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
 {
 	int ret = 0;
-	u16 reg_907 = dib8000_read_word(state, 907), reg_908 = dib8000_read_word(state, 908);
+	u16 reg, reg_907 = dib8000_read_word(state, 907);
+	u16 reg_908 = dib8000_read_word(state, 908);
 
 	switch (no) {
 	case DIBX000_SLOW_ADC_ON:
-		reg_908 |= (1 << 1) | (1 << 0);
-		ret |= dib8000_write_word(state, 908, reg_908);
-		reg_908 &= ~(1 << 1);
+		if (state->revision != 0x8090) {
+			reg_908 |= (1 << 1) | (1 << 0);
+			ret |= dib8000_write_word(state, 908, reg_908);
+			reg_908 &= ~(1 << 1);
+		} else {
+			reg = dib8000_read_word(state, 1925);
+			/* en_slowAdc = 1 & reset_sladc = 1 */
+			dib8000_write_word(state, 1925, reg |
+					(1<<4) | (1<<2));
+
+			/* read acces to make it works... strange ... */
+			reg = dib8000_read_word(state, 1925);
+			msleep(20);
+			/* en_slowAdc = 1 & reset_sladc = 0 */
+			dib8000_write_word(state, 1925, reg & ~(1<<4));
+
+			reg = dib8000_read_word(state, 921) & ~((0x3 << 14)
+					| (0x3 << 12));
+			/* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ;
+			   (Vin2 = Vcm) */
+			dib8000_write_word(state, 921, reg | (1 << 14)
+					| (3 << 12));
+		}
 		break;
 
 	case DIBX000_SLOW_ADC_OFF:
+		if (state->revision == 0x8090) {
+			reg = dib8000_read_word(state, 1925);
+			/* reset_sladc = 1 en_slowAdc = 0 */
+			dib8000_write_word(state, 1925,
+					(reg & ~(1<<2)) | (1<<4));
+		}
 		reg_908 |= (1 << 1) | (1 << 0);
 		break;
 
@@ -521,7 +584,12 @@
 
 static int dib8000_sad_calib(struct dib8000_state *state)
 {
-/* internal */
+	if (state->revision == 0x8090) {
+		dprintk("%s: the sad calibration is not needed for the dib8096P",
+				__func__);
+		return 0;
+	}
+	/* internal */
 	dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
 	dib8000_write_word(state, 924, 776);	// 0.625*3.3 / 4096
 
@@ -546,48 +614,129 @@
 static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
 {
 	dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
-	dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff));	/* P_sec_len */
-	dib8000_write_word(state, 24, (u16) ((bw->internal * 1000) & 0xffff));
+	if (state->revision != 0x8090) {
+		dib8000_write_word(state, 23,
+				(u16) (((bw->internal * 1000) >> 16) & 0xffff));
+		dib8000_write_word(state, 24,
+				(u16) ((bw->internal * 1000) & 0xffff));
+	} else {
+		dib8000_write_word(state, 23, (u16) (((bw->internal / 2 * 1000) >> 16) & 0xffff));
+		dib8000_write_word(state, 24,
+				(u16) ((bw->internal  / 2 * 1000) & 0xffff));
+	}
 	dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
 	dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
 	dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
 
-	dib8000_write_word(state, 922, bw->sad_cfg);
+	if (state->revision != 0x8090)
+		dib8000_write_word(state, 922, bw->sad_cfg);
 }
 
 static void dib8000_reset_pll(struct dib8000_state *state)
 {
 	const struct dibx000_bandwidth_config *pll = state->cfg.pll;
-	u16 clk_cfg1;
+	u16 clk_cfg1, reg;
 
-	// clk_cfg0
-	dib8000_write_word(state, 901, (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
+	if (state->revision != 0x8090) {
+		dib8000_write_word(state, 901,
+				(pll->pll_prediv << 8) | (pll->pll_ratio << 0));
 
-	// clk_cfg1
-	clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
-		(pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) |
-		(pll->pll_range << 1) | (pll->pll_reset << 0);
+		clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
+			(pll->bypclk_div << 5) | (pll->enable_refdiv << 4) |
+			(1 << 3) | (pll->pll_range << 1) |
+			(pll->pll_reset << 0);
 
-	dib8000_write_word(state, 902, clk_cfg1);
-	clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
-	dib8000_write_word(state, 902, clk_cfg1);
+		dib8000_write_word(state, 902, clk_cfg1);
+		clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
+		dib8000_write_word(state, 902, clk_cfg1);
 
-	dprintk("clk_cfg1: 0x%04x", clk_cfg1);	/* 0x507 1 0 1 000 0 0 11 1 */
+		dprintk("clk_cfg1: 0x%04x", clk_cfg1);
 
-	/* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
-	if (state->cfg.pll->ADClkSrc == 0)
-		dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) |
-				(pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
-	else if (state->cfg.refclksel != 0)
-		dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
-				((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) |
-				(pll->ADClkSrc << 7) | (0 << 1));
-	else
-		dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
+		/* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
+		if (state->cfg.pll->ADClkSrc == 0)
+			dib8000_write_word(state, 904,
+					(0 << 15) | (0 << 12) | (0 << 10) |
+					(pll->modulo << 8) |
+					(pll->ADClkSrc << 7) | (0 << 1));
+		else if (state->cfg.refclksel != 0)
+			dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
+					((state->cfg.refclksel & 0x3) << 10) |
+					(pll->modulo << 8) |
+					(pll->ADClkSrc << 7) | (0 << 1));
+		else
+			dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
+					(3 << 10) | (pll->modulo << 8) |
+					(pll->ADClkSrc << 7) | (0 << 1));
+	} else {
+		dib8000_write_word(state, 1856, (!pll->pll_reset<<13) |
+				(pll->pll_range<<12) | (pll->pll_ratio<<6) |
+				(pll->pll_prediv));
+
+		reg = dib8000_read_word(state, 1857);
+		dib8000_write_word(state, 1857, reg|(!pll->pll_bypass<<15));
+
+		reg = dib8000_read_word(state, 1858); /* Force clk out pll /2 */
+		dib8000_write_word(state, 1858, reg | 1);
+
+		dib8000_write_word(state, 904, (pll->modulo << 8));
+	}
 
 	dib8000_reset_pll_common(state, pll);
 }
 
+int dib8000_update_pll(struct dvb_frontend *fe,
+		struct dibx000_bandwidth_config *pll)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	u16 reg_1857, reg_1856 = dib8000_read_word(state, 1856);
+	u8 loopdiv, prediv;
+	u32 internal, xtal;
+
+	/* get back old values */
+	prediv = reg_1856 & 0x3f;
+	loopdiv = (reg_1856 >> 6) & 0x3f;
+
+	if ((pll != NULL) && (pll->pll_prediv != prediv ||
+				pll->pll_ratio != loopdiv)) {
+		dprintk("Updating pll (prediv: old =  %d new = %d ; loopdiv : old = %d new = %d)", prediv, pll->pll_prediv, loopdiv, pll->pll_ratio);
+		reg_1856 &= 0xf000;
+		reg_1857 = dib8000_read_word(state, 1857);
+		/* disable PLL */
+		dib8000_write_word(state, 1857, reg_1857 & ~(1 << 15));
+
+		dib8000_write_word(state, 1856, reg_1856 |
+				((pll->pll_ratio & 0x3f) << 6) |
+				(pll->pll_prediv & 0x3f));
+
+		/* write new system clk into P_sec_len */
+		internal = dib8000_read32(state, 23) / 1000;
+		dprintk("Old Internal = %d", internal);
+		xtal = 2 * (internal / loopdiv) * prediv;
+		internal = 1000 * (xtal/pll->pll_prediv) * pll->pll_ratio;
+		dprintk("Xtal = %d , New Fmem = %d New Fdemod = %d, New Fsampling = %d", xtal, internal/1000, internal/2000, internal/8000);
+		dprintk("New Internal = %d", internal);
+
+		dib8000_write_word(state, 23,
+				(u16) (((internal / 2) >> 16) & 0xffff));
+		dib8000_write_word(state, 24, (u16) ((internal / 2) & 0xffff));
+		/* enable PLL */
+		dib8000_write_word(state, 1857, reg_1857 | (1 << 15));
+
+		while (((dib8000_read_word(state, 1856)>>15)&0x1) != 1)
+			dprintk("Waiting for PLL to lock");
+
+		/* verify */
+		reg_1856 = dib8000_read_word(state, 1856);
+		dprintk("PLL Updated with prediv = %d and loopdiv = %d",
+				reg_1856&0x3f, (reg_1856>>6)&0x3f);
+
+		return 0;
+	}
+	return -EINVAL;
+}
+EXPORT_SYMBOL(dib8000_update_pll);
+
+
 static int dib8000_reset_gpio(struct dib8000_state *st)
 {
 	/* reset the GPIOs */
@@ -721,9 +870,6 @@
 		(3 << 5) |		/* P_ctrl_pre_freq_step=3 */
 		(1 << 0),		/* P_pre_freq_win_len=1 */
 
-	1, 903,
-	(0 << 4) | 2,		// P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW)
-
 	0,
 };
 
@@ -740,7 +886,8 @@
 	}
 
 	value = dib8000_i2c_read16(client, 897);
-	if (value != 0x8000 && value != 0x8001 && value != 0x8002) {
+	if (value != 0x8000 && value != 0x8001 &&
+			value != 0x8002 && value != 0x8090) {
 		dprintk("wrong Device ID (%x)", value);
 		return 0;
 	}
@@ -755,6 +902,9 @@
 	case 0x8002:
 		dprintk("found DiB8000C");
 		break;
+	case 0x8090:
+		dprintk("found DiB8096P");
+		break;
 	}
 	return value;
 }
@@ -763,17 +913,19 @@
 {
 	struct dib8000_state *state = fe->demodulator_priv;
 
-	dib8000_write_word(state, 1287, 0x0003);	/* sram lead in, rdy */
-
 	if ((state->revision = dib8000_identify(&state->i2c)) == 0)
 		return -EINVAL;
 
+	/* sram lead in, rdy */
+	if (state->revision != 0x8090)
+		dib8000_write_word(state, 1287, 0x0003);
+
 	if (state->revision == 0x8000)
 		dprintk("error : dib8000 MA not supported");
 
 	dibx000_reset_i2c_master(&state->i2c_master);
 
-	dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
+	dib8000_set_power_mode(state, DIB8000_POWER_ALL);
 
 	/* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
 	dib8000_set_adc_state(state, DIBX000_VBG_ENABLE);
@@ -782,8 +934,10 @@
 	dib8000_write_word(state, 770, 0xffff);
 	dib8000_write_word(state, 771, 0xffff);
 	dib8000_write_word(state, 772, 0xfffc);
-	dib8000_write_word(state, 898, 0x000c);	// sad
-	dib8000_write_word(state, 1280, 0x004d);
+	if (state->revision == 0x8090)
+		dib8000_write_word(state, 1280, 0x0045);
+	else
+		dib8000_write_word(state, 1280, 0x004d);
 	dib8000_write_word(state, 1281, 0x000c);
 
 	dib8000_write_word(state, 770, 0x0000);
@@ -794,19 +948,25 @@
 	dib8000_write_word(state, 1281, 0x0000);
 
 	/* drives */
-	if (state->cfg.drives)
-		dib8000_write_word(state, 906, state->cfg.drives);
-	else {
-		dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
-		dib8000_write_word(state, 906, 0x2d98);	// min drive SDRAM - not optimal - adjust
+	if (state->revision != 0x8090) {
+		if (state->cfg.drives)
+			dib8000_write_word(state, 906, state->cfg.drives);
+		else {
+			dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
+			/* min drive SDRAM - not optimal - adjust */
+			dib8000_write_word(state, 906, 0x2d98);
+		}
 	}
 
 	dib8000_reset_pll(state);
+	if (state->revision != 0x8090)
+		dib8000_write_word(state, 898, 0x0004);
 
 	if (dib8000_reset_gpio(state) != 0)
 		dprintk("GPIO reset was not successful.");
 
-	if (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0)
+	if ((state->revision != 0x8090) &&
+			(dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0))
 		dprintk("OUTPUT_MODE could not be resetted.");
 
 	state->current_agc = NULL;
@@ -832,6 +992,8 @@
 			l = *n++;
 		}
 	}
+	if (state->revision != 0x8090)
+		dib8000_write_word(state, 903, (0 << 4) | 2);
 	state->isdbt_cfg_loaded = 0;
 
 	//div_cfg override for special configs
@@ -844,10 +1006,12 @@
 	dib8000_set_bandwidth(fe, 6000);
 
 	dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
-	dib8000_sad_calib(state);
-	dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
+	if (state->revision != 0x8090) {
+		dib8000_sad_calib(state);
+		dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
+	}
 
-	dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
+	dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
 
 	return 0;
 }
@@ -879,6 +1043,8 @@
 {
 	struct dibx000_agc_config *agc = NULL;
 	int i;
+	u16 reg;
+
 	if (state->current_band == band && state->current_agc != NULL)
 		return 0;
 	state->current_band = band;
@@ -914,6 +1080,12 @@
 		dib8000_write_word(state, 106, state->wbd_ref);
 	else			// use default
 		dib8000_write_word(state, 106, agc->wbd_ref);
+
+	if (state->revision == 0x8090) {
+		reg = dib8000_read_word(state, 922) & (0x3 << 2);
+		dib8000_write_word(state, 922, reg | (agc->wbd_sel << 2));
+	}
+
 	dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
 	dib8000_write_word(state, 108, agc->agc1_max);
 	dib8000_write_word(state, 109, agc->agc1_min);
@@ -925,7 +1097,10 @@
 	dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
 
 	dib8000_write_word(state, 75, agc->agc1_pt3);
-	dib8000_write_word(state, 923, (dib8000_read_word(state, 923) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2));	/*LB : 929 -> 923 */
+	if (state->revision != 0x8090)
+		dib8000_write_word(state, 923,
+				(dib8000_read_word(state, 923) & 0xffe3) |
+				(agc->wbd_inv << 4) | (agc->wbd_sel << 2));
 
 	return 0;
 }
@@ -968,14 +1143,30 @@
 {
 	struct dib8000_state *state = fe->demodulator_priv;
 	enum frontend_tune_state *tune_state = &state->tune_state;
-
 	int ret = 0;
+	u16 reg, upd_demod_gain_period = 0x8000;
 
 	switch (*tune_state) {
 	case CT_AGC_START:
 		// set power-up level: interf+analog+AGC
 
-		dib8000_set_adc_state(state, DIBX000_ADC_ON);
+		if (state->revision != 0x8090)
+			dib8000_set_adc_state(state, DIBX000_ADC_ON);
+		else {
+			dib8000_set_power_mode(state, DIB8000_POWER_ALL);
+
+			reg = dib8000_read_word(state, 1947)&0xff00;
+			dib8000_write_word(state, 1946,
+					upd_demod_gain_period & 0xFFFF);
+			/* bit 14 = enDemodGain */
+			dib8000_write_word(state, 1947, reg | (1<<14) |
+					((upd_demod_gain_period >> 16) & 0xFF));
+
+			/* enable adc i & q */
+			reg = dib8000_read_word(state, 1920);
+			dib8000_write_word(state, 1920, (reg | 0x3) &
+					(~(1 << 7)));
+		}
 
 		if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
 			*tune_state = CT_AGC_STOP;
@@ -1026,6 +1217,579 @@
 
 }
 
+static void dib8096p_host_bus_drive(struct dib8000_state *state, u8 drive)
+{
+	u16 reg;
+
+	drive &= 0x7;
+
+	/* drive host bus 2, 3, 4 */
+	reg = dib8000_read_word(state, 1798) &
+		~(0x7 | (0x7 << 6) | (0x7 << 12));
+	reg |= (drive<<12) | (drive<<6) | drive;
+	dib8000_write_word(state, 1798, reg);
+
+	/* drive host bus 5,6 */
+	reg = dib8000_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
+	reg |= (drive<<8) | (drive<<2);
+	dib8000_write_word(state, 1799, reg);
+
+	/* drive host bus 7, 8, 9 */
+	reg = dib8000_read_word(state, 1800) &
+		~(0x7 | (0x7 << 6) | (0x7 << 12));
+	reg |= (drive<<12) | (drive<<6) | drive;
+	dib8000_write_word(state, 1800, reg);
+
+	/* drive host bus 10, 11 */
+	reg = dib8000_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
+	reg |= (drive<<8) | (drive<<2);
+	dib8000_write_word(state, 1801, reg);
+
+	/* drive host bus 12, 13, 14 */
+	reg = dib8000_read_word(state, 1802) &
+		~(0x7 | (0x7 << 6) | (0x7 << 12));
+	reg |= (drive<<12) | (drive<<6) | drive;
+	dib8000_write_word(state, 1802, reg);
+}
+
+static u32 dib8096p_calcSyncFreq(u32 P_Kin, u32 P_Kout,
+		u32 insertExtSynchro, u32 syncSize)
+{
+	u32 quantif = 3;
+	u32 nom = (insertExtSynchro * P_Kin+syncSize);
+	u32 denom = P_Kout;
+	u32 syncFreq = ((nom << quantif) / denom);
+
+	if ((syncFreq & ((1 << quantif) - 1)) != 0)
+		syncFreq = (syncFreq >> quantif) + 1;
+	else
+		syncFreq = (syncFreq >> quantif);
+
+	if (syncFreq != 0)
+		syncFreq = syncFreq - 1;
+
+	return syncFreq;
+}
+
+static void dib8096p_cfg_DibTx(struct dib8000_state *state, u32 P_Kin,
+		u32 P_Kout, u32 insertExtSynchro, u32 synchroMode,
+		u32 syncWord, u32 syncSize)
+{
+	dprintk("Configure DibStream Tx");
+
+	dib8000_write_word(state, 1615, 1);
+	dib8000_write_word(state, 1603, P_Kin);
+	dib8000_write_word(state, 1605, P_Kout);
+	dib8000_write_word(state, 1606, insertExtSynchro);
+	dib8000_write_word(state, 1608, synchroMode);
+	dib8000_write_word(state, 1609, (syncWord >> 16) & 0xffff);
+	dib8000_write_word(state, 1610, syncWord & 0xffff);
+	dib8000_write_word(state, 1612, syncSize);
+	dib8000_write_word(state, 1615, 0);
+}
+
+static void dib8096p_cfg_DibRx(struct dib8000_state *state, u32 P_Kin,
+		u32 P_Kout, u32 synchroMode, u32 insertExtSynchro,
+		u32 syncWord, u32 syncSize, u32 dataOutRate)
+{
+	u32 syncFreq;
+
+	dprintk("Configure DibStream Rx synchroMode = %d", synchroMode);
+
+	if ((P_Kin != 0) && (P_Kout != 0)) {
+		syncFreq = dib8096p_calcSyncFreq(P_Kin, P_Kout,
+				insertExtSynchro, syncSize);
+		dib8000_write_word(state, 1542, syncFreq);
+	}
+
+	dib8000_write_word(state, 1554, 1);
+	dib8000_write_word(state, 1536, P_Kin);
+	dib8000_write_word(state, 1537, P_Kout);
+	dib8000_write_word(state, 1539, synchroMode);
+	dib8000_write_word(state, 1540, (syncWord >> 16) & 0xffff);
+	dib8000_write_word(state, 1541, syncWord & 0xffff);
+	dib8000_write_word(state, 1543, syncSize);
+	dib8000_write_word(state, 1544, dataOutRate);
+	dib8000_write_word(state, 1554, 0);
+}
+
+static void dib8096p_enMpegMux(struct dib8000_state *state, int onoff)
+{
+	u16 reg_1287;
+
+	reg_1287 = dib8000_read_word(state, 1287);
+
+	switch (onoff) {
+	case 1:
+			reg_1287 &= ~(1 << 8);
+			break;
+	case 0:
+			reg_1287 |= (1 << 8);
+			break;
+	}
+
+	dib8000_write_word(state, 1287, reg_1287);
+}
+
+static void dib8096p_configMpegMux(struct dib8000_state *state,
+		u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
+{
+	u16 reg_1287;
+
+	dprintk("Enable Mpeg mux");
+
+	dib8096p_enMpegMux(state, 0);
+
+	/* If the input mode is MPEG do not divide the serial clock */
+	if ((enSerialMode == 1) && (state->input_mode_mpeg == 1))
+		enSerialClkDiv2 = 0;
+
+	reg_1287 = ((pulseWidth & 0x1f) << 3) |
+		((enSerialMode & 0x1) << 2) | (enSerialClkDiv2 & 0x1);
+	dib8000_write_word(state, 1287, reg_1287);
+
+	dib8096p_enMpegMux(state, 1);
+}
+
+static void dib8096p_setDibTxMux(struct dib8000_state *state, int mode)
+{
+	u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 7);
+
+	switch (mode) {
+	case MPEG_ON_DIBTX:
+			dprintk("SET MPEG ON DIBSTREAM TX");
+			dib8096p_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
+			reg_1288 |= (1 << 9); break;
+	case DIV_ON_DIBTX:
+			dprintk("SET DIV_OUT ON DIBSTREAM TX");
+			dib8096p_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
+			reg_1288 |= (1 << 8); break;
+	case ADC_ON_DIBTX:
+			dprintk("SET ADC_OUT ON DIBSTREAM TX");
+			dib8096p_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
+			reg_1288 |= (1 << 7); break;
+	default:
+			break;
+	}
+	dib8000_write_word(state, 1288, reg_1288);
+}
+
+static void dib8096p_setHostBusMux(struct dib8000_state *state, int mode)
+{
+	u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 4);
+
+	switch (mode) {
+	case DEMOUT_ON_HOSTBUS:
+			dprintk("SET DEM OUT OLD INTERF ON HOST BUS");
+			dib8096p_enMpegMux(state, 0);
+			reg_1288 |= (1 << 6);
+			break;
+	case DIBTX_ON_HOSTBUS:
+			dprintk("SET DIBSTREAM TX ON HOST BUS");
+			dib8096p_enMpegMux(state, 0);
+			reg_1288 |= (1 << 5);
+			break;
+	case MPEG_ON_HOSTBUS:
+			dprintk("SET MPEG MUX ON HOST BUS");
+			reg_1288 |= (1 << 4);
+			break;
+	default:
+			break;
+	}
+	dib8000_write_word(state, 1288, reg_1288);
+}
+
+static int dib8096p_set_diversity_in(struct dvb_frontend *fe, int onoff)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	u16 reg_1287;
+
+	switch (onoff) {
+	case 0: /* only use the internal way - not the diversity input */
+			dprintk("%s mode OFF : by default Enable Mpeg INPUT",
+					__func__);
+			/* outputRate = 8 */
+			dib8096p_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0);
+
+			/* Do not divide the serial clock of MPEG MUX in
+			   SERIAL MODE in case input mode MPEG is used */
+			reg_1287 = dib8000_read_word(state, 1287);
+			/* enSerialClkDiv2 == 1 ? */
+			if ((reg_1287 & 0x1) == 1) {
+				/* force enSerialClkDiv2 = 0 */
+				reg_1287 &= ~0x1;
+				dib8000_write_word(state, 1287, reg_1287);
+			}
+			state->input_mode_mpeg = 1;
+			break;
+	case 1: /* both ways */
+	case 2: /* only the diversity input */
+			dprintk("%s ON : Enable diversity INPUT", __func__);
+			dib8096p_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
+			state->input_mode_mpeg = 0;
+			break;
+	}
+
+	dib8000_set_diversity_in(state->fe[0], onoff);
+	return 0;
+}
+
+static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	u16 outreg, smo_mode, fifo_threshold;
+	u8 prefer_mpeg_mux_use = 1;
+	int ret = 0;
+
+	dib8096p_host_bus_drive(state, 1);
+
+	fifo_threshold = 1792;
+	smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
+	outreg   = dib8000_read_word(state, 1286) &
+		~((1 << 10) | (0x7 << 6) | (1 << 1));
+
+	switch (mode) {
+	case OUTMODE_HIGH_Z:
+			outreg = 0;
+			break;
+
+	case OUTMODE_MPEG2_SERIAL:
+			if (prefer_mpeg_mux_use) {
+				dprintk("dib8096P setting output mode TS_SERIAL using Mpeg Mux");
+				dib8096p_configMpegMux(state, 3, 1, 1);
+				dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS);
+			} else {/* Use Smooth block */
+				dprintk("dib8096P setting output mode TS_SERIAL using Smooth bloc");
+				dib8096p_setHostBusMux(state,
+						DEMOUT_ON_HOSTBUS);
+				outreg |= (2 << 6) | (0 << 1);
+			}
+			break;
+
+	case OUTMODE_MPEG2_PAR_GATED_CLK:
+			if (prefer_mpeg_mux_use) {
+				dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
+				dib8096p_configMpegMux(state, 2, 0, 0);
+				dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS);
+			} else { /* Use Smooth block */
+				dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Smooth block");
+				dib8096p_setHostBusMux(state,
+						DEMOUT_ON_HOSTBUS);
+				outreg |= (0 << 6);
+			}
+			break;
+
+	case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */
+			dprintk("dib8096P setting output mode TS_PARALLEL_CONT using Smooth block");
+			dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
+			outreg |= (1 << 6);
+			break;
+
+	case OUTMODE_MPEG2_FIFO:
+			/* Using Smooth block because not supported
+			   by new Mpeg Mux bloc */
+			dprintk("dib8096P setting output mode TS_FIFO using Smooth block");
+			dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
+			outreg |= (5 << 6);
+			smo_mode |= (3 << 1);
+			fifo_threshold = 512;
+			break;
+
+	case OUTMODE_DIVERSITY:
+			dprintk("dib8096P setting output mode MODE_DIVERSITY");
+			dib8096p_setDibTxMux(state, DIV_ON_DIBTX);
+			dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
+			break;
+
+	case OUTMODE_ANALOG_ADC:
+			dprintk("dib8096P setting output mode MODE_ANALOG_ADC");
+			dib8096p_setDibTxMux(state, ADC_ON_DIBTX);
+			dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
+			break;
+	}
+
+	if (mode != OUTMODE_HIGH_Z)
+		outreg |= (1<<10);
+
+	dprintk("output_mpeg2_in_188_bytes = %d",
+			state->cfg.output_mpeg2_in_188_bytes);
+	if (state->cfg.output_mpeg2_in_188_bytes)
+		smo_mode |= (1 << 5);
+
+	ret |= dib8000_write_word(state, 299, smo_mode);
+	/* synchronous fread */
+	ret |= dib8000_write_word(state, 299 + 1, fifo_threshold);
+	ret |= dib8000_write_word(state, 1286, outreg);
+
+	return ret;
+}
+
+static int map_addr_to_serpar_number(struct i2c_msg *msg)
+{
+	if (msg->buf[0] <= 15)
+		msg->buf[0] -= 1;
+	else if (msg->buf[0] == 17)
+		msg->buf[0] = 15;
+	else if (msg->buf[0] == 16)
+		msg->buf[0] = 17;
+	else if (msg->buf[0] == 19)
+		msg->buf[0] = 16;
+	else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
+		msg->buf[0] -= 3;
+	else if (msg->buf[0] == 28)
+		msg->buf[0] = 23;
+	else if (msg->buf[0] == 99)
+		msg->buf[0] = 99;
+	else
+		return -EINVAL;
+	return 0;
+}
+
+static int dib8096p_tuner_write_serpar(struct i2c_adapter *i2c_adap,
+		struct i2c_msg msg[], int num)
+{
+	struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
+	u8 n_overflow = 1;
+	u16 i = 1000;
+	u16 serpar_num = msg[0].buf[0];
+
+	while (n_overflow == 1 && i) {
+		n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1;
+		i--;
+		if (i == 0)
+			dprintk("Tuner ITF: write busy (overflow)");
+	}
+	dib8000_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
+	dib8000_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
+
+	return num;
+}
+
+static int dib8096p_tuner_read_serpar(struct i2c_adapter *i2c_adap,
+		struct i2c_msg msg[], int num)
+{
+	struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
+	u8 n_overflow = 1, n_empty = 1;
+	u16 i = 1000;
+	u16 serpar_num = msg[0].buf[0];
+	u16 read_word;
+
+	while (n_overflow == 1 && i) {
+		n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1;
+		i--;
+		if (i == 0)
+			dprintk("TunerITF: read busy (overflow)");
+	}
+	dib8000_write_word(state, 1985, (0<<6) | (serpar_num&0x3f));
+
+	i = 1000;
+	while (n_empty == 1 && i) {
+		n_empty = dib8000_read_word(state, 1984)&0x1;
+		i--;
+		if (i == 0)
+			dprintk("TunerITF: read busy (empty)");
+	}
+
+	read_word = dib8000_read_word(state, 1987);
+	msg[1].buf[0] = (read_word >> 8) & 0xff;
+	msg[1].buf[1] = (read_word) & 0xff;
+
+	return num;
+}
+
+static int dib8096p_tuner_rw_serpar(struct i2c_adapter *i2c_adap,
+		struct i2c_msg msg[], int num)
+{
+	if (map_addr_to_serpar_number(&msg[0]) == 0) {
+		if (num == 1) /* write */
+			return dib8096p_tuner_write_serpar(i2c_adap, msg, 1);
+		else /* read */
+			return dib8096p_tuner_read_serpar(i2c_adap, msg, 2);
+	}
+	return num;
+}
+
+static int dib8096p_rw_on_apb(struct i2c_adapter *i2c_adap,
+		struct i2c_msg msg[], int num, u16 apb_address)
+{
+	struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
+	u16 word;
+
+	if (num == 1) {		/* write */
+		dib8000_write_word(state, apb_address,
+				((msg[0].buf[1] << 8) | (msg[0].buf[2])));
+	} else {
+		word = dib8000_read_word(state, apb_address);
+		msg[1].buf[0] = (word >> 8) & 0xff;
+		msg[1].buf[1] = (word) & 0xff;
+	}
+	return num;
+}
+
+static int dib8096p_tuner_xfer(struct i2c_adapter *i2c_adap,
+		struct i2c_msg msg[], int num)
+{
+	struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
+	u16 apb_address = 0, word;
+	int i = 0;
+
+	switch (msg[0].buf[0]) {
+	case 0x12:
+			apb_address = 1920;
+			break;
+	case 0x14:
+			apb_address = 1921;
+			break;
+	case 0x24:
+			apb_address = 1922;
+			break;
+	case 0x1a:
+			apb_address = 1923;
+			break;
+	case 0x22:
+			apb_address = 1924;
+			break;
+	case 0x33:
+			apb_address = 1926;
+			break;
+	case 0x34:
+			apb_address = 1927;
+			break;
+	case 0x35:
+			apb_address = 1928;
+			break;
+	case 0x36:
+			apb_address = 1929;
+			break;
+	case 0x37:
+			apb_address = 1930;
+			break;
+	case 0x38:
+			apb_address = 1931;
+			break;
+	case 0x39:
+			apb_address = 1932;
+			break;
+	case 0x2a:
+			apb_address = 1935;
+			break;
+	case 0x2b:
+			apb_address = 1936;
+			break;
+	case 0x2c:
+			apb_address = 1937;
+			break;
+	case 0x2d:
+			apb_address = 1938;
+			break;
+	case 0x2e:
+			apb_address = 1939;
+			break;
+	case 0x2f:
+			apb_address = 1940;
+			break;
+	case 0x30:
+			apb_address = 1941;
+			break;
+	case 0x31:
+			apb_address = 1942;
+			break;
+	case 0x32:
+			apb_address = 1943;
+			break;
+	case 0x3e:
+			apb_address = 1944;
+			break;
+	case 0x3f:
+			apb_address = 1945;
+			break;
+	case 0x40:
+			apb_address = 1948;
+			break;
+	case 0x25:
+			apb_address = 936;
+			break;
+	case 0x26:
+			apb_address = 937;
+			break;
+	case 0x27:
+			apb_address = 938;
+			break;
+	case 0x28:
+			apb_address = 939;
+			break;
+	case 0x1d:
+			/* get sad sel request */
+			i = ((dib8000_read_word(state, 921) >> 12)&0x3);
+			word = dib8000_read_word(state, 924+i);
+			msg[1].buf[0] = (word >> 8) & 0xff;
+			msg[1].buf[1] = (word) & 0xff;
+			return num;
+	case 0x1f:
+			if (num == 1) {	/* write */
+				word = (u16) ((msg[0].buf[1] << 8) |
+						msg[0].buf[2]);
+				/* in the VGAMODE Sel are located on bit 0/1 */
+				word &= 0x3;
+				word = (dib8000_read_word(state, 921) &
+						~(3<<12)) | (word<<12);
+				/* Set the proper input */
+				dib8000_write_word(state, 921, word);
+				return num;
+			}
+	}
+
+	if (apb_address != 0) /* R/W acces via APB */
+		return dib8096p_rw_on_apb(i2c_adap, msg, num, apb_address);
+	else  /* R/W access via SERPAR  */
+		return dib8096p_tuner_rw_serpar(i2c_adap, msg, num);
+
+	return 0;
+}
+
+static u32 dib8096p_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm dib8096p_tuner_xfer_algo = {
+	.master_xfer = dib8096p_tuner_xfer,
+	.functionality = dib8096p_i2c_func,
+};
+
+struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe)
+{
+	struct dib8000_state *st = fe->demodulator_priv;
+	return &st->dib8096p_tuner_adap;
+}
+EXPORT_SYMBOL(dib8096p_get_i2c_tuner);
+
+int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	u16 en_cur_state;
+
+	dprintk("sleep dib8096p: %d", onoff);
+
+	en_cur_state = dib8000_read_word(state, 1922);
+
+	/* LNAs and MIX are ON and therefore it is a valid configuration */
+	if (en_cur_state > 0xff)
+		state->tuner_enable = en_cur_state ;
+
+	if (onoff)
+		en_cur_state &= 0x00ff;
+	else {
+		if (state->tuner_enable != 0)
+			en_cur_state = state->tuner_enable;
+	}
+
+	dib8000_write_word(state, 1922, en_cur_state);
+
+	return 0;
+}
+EXPORT_SYMBOL(dib8096p_tuner_sleep);
+
 static const s32 lut_1000ln_mant[] =
 {
 	908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
@@ -1051,6 +1815,26 @@
 }
 EXPORT_SYMBOL(dib8000_get_adc_power);
 
+int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	int val = 0;
+
+	switch (IQ) {
+	case 1:
+			val = dib8000_read_word(state, 403);
+			break;
+	case 0:
+			val = dib8000_read_word(state, 404);
+			break;
+	}
+	if (val  & 0x200)
+		val -= 1024;
+
+	return val;
+}
+EXPORT_SYMBOL(dib8090p_get_dc_power);
+
 static void dib8000_update_timf(struct dib8000_state *state)
 {
 	u32 timf = state->timf = dib8000_read32(state, 435);
@@ -1060,6 +1844,26 @@
 	dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
 }
 
+u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+
+	switch (op) {
+	case DEMOD_TIMF_SET:
+			state->timf = timf;
+			break;
+	case DEMOD_TIMF_UPDATE:
+			dib8000_update_timf(state);
+			break;
+	case DEMOD_TIMF_GET:
+			break;
+	}
+	dib8000_set_bandwidth(state->fe[0], 6000);
+
+	return state->timf;
+}
+EXPORT_SYMBOL(dib8000_ctrl_timf);
+
 static const u16 adc_target_16dB[11] = {
 	(1 << 13) - 825 - 117,
 	(1 << 13) - 837 - 117,
@@ -1086,6 +1890,9 @@
 	u16 init_prbs = 0xfff;
 	u16 ana_gain = 0;
 
+	if (state->revision == 0x8090)
+		dib8000_init_sdram(state);
+
 	if (state->ber_monitored_layer != LAYER_ALL)
 		dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
 	else
@@ -1418,7 +2225,10 @@
 	dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
 
 	state->differential_constellation = (seg_diff_mask != 0);
-	dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
+	if (state->revision != 0x8090)
+		dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
+	else
+		dib8096p_set_diversity_in(state->fe[0], state->diversity_onoff);
 
 	if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
 		if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
@@ -1870,7 +2680,7 @@
 {
 	struct dib8000_state *state = fe->demodulator_priv;
 	int ret = 0;
-	u16 value, mode = fft_to_mode(state);
+	u16 lock, value, mode = fft_to_mode(state);
 
 	// we are already tuned - just resuming from suspend
 	if (state == NULL)
@@ -1924,7 +2734,11 @@
 	}
 
 	// we achieved a coff_cpil_lock - it's time to update the timf
-	if ((dib8000_read_word(state, 568) >> 11) & 0x1)
+	if (state->revision != 0x8090)
+		lock = dib8000_read_word(state, 568);
+	else
+		lock = dib8000_read_word(state, 570);
+	if ((lock >> 11) & 0x1)
 		dib8000_update_timf(state);
 
 	//now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start
@@ -1946,11 +2760,14 @@
 	u8 index_frontend;
 	int ret;
 
-	dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
+	dib8000_set_power_mode(state, DIB8000_POWER_ALL);
 	dib8000_set_adc_state(state, DIBX000_ADC_ON);
 	if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
 		dprintk("could not start Slow ADC");
 
+	if (state->revision != 0x8090)
+		dib8000_sad_calib(state);
+
 	for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
 		ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]);
 		if (ret < 0)
@@ -1972,8 +2789,9 @@
 			return ret;
 	}
 
-	dib8000_set_output_mode(fe, OUTMODE_HIGH_Z);
-	dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
+	if (state->revision != 0x8090)
+		dib8000_set_output_mode(fe, OUTMODE_HIGH_Z);
+	dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
 	return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF);
 }
 
@@ -2028,7 +2846,10 @@
 
 	fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
 
-	val = dib8000_read_word(state, 570);
+	if (state->revision == 0x8090)
+		val = dib8000_read_word(state, 572);
+	else
+		val = dib8000_read_word(state, 570);
 	fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
 	switch ((val & 0x30) >> 4) {
 	case 1:
@@ -2158,7 +2979,12 @@
 		state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT;
 		memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
 
-		dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z);
+		if (state->revision != 0x8090)
+			dib8000_set_output_mode(state->fe[index_frontend],
+					OUTMODE_HIGH_Z);
+		else
+			dib8096p_set_output_mode(state->fe[index_frontend],
+					OUTMODE_HIGH_Z);
 		if (state->fe[index_frontend]->ops.tuner_ops.set_params)
 			state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend], fep);
 
@@ -2215,7 +3041,7 @@
 			 ((state->fe[0]->dtv_property_cache.layer[1].segment_count == 0) ||
 			  ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
 			 ((state->fe[0]->dtv_property_cache.layer[2].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
-		int i = 80000;
+		int i = 100;
 		u8 found = 0;
 		u8 tune_failed = 0;
 
@@ -2243,6 +3069,7 @@
 					default:
 						 dprintk("unhandled autosearch result");
 					case 1:
+						 tune_failed |= (1 << index_frontend);
 						 dprintk("autosearch failed for the frontend%i", index_frontend);
 						 break;
 					}
@@ -2268,14 +3095,37 @@
 		ret = dib8000_tune(state->fe[index_frontend]);
 
 	/* set output mode and diversity input */
-	dib8000_set_output_mode(state->fe[0], state->cfg.output_mode);
-	for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
-		dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY);
-		dib8000_set_diversity_in(state->fe[index_frontend-1], 1);
-	}
+	if (state->revision != 0x8090) {
+		dib8000_set_output_mode(state->fe[0], state->cfg.output_mode);
+		for (index_frontend = 1;
+				(index_frontend < MAX_NUMBER_OF_FRONTENDS) &&
+				(state->fe[index_frontend] != NULL);
+				index_frontend++) {
+			dib8000_set_output_mode(state->fe[index_frontend],
+					OUTMODE_DIVERSITY);
+			dib8000_set_diversity_in(state->fe[index_frontend-1], 1);
+		}
 
-	/* turn off the diversity of the last chip */
-	dib8000_set_diversity_in(state->fe[index_frontend-1], 0);
+		/* turn off the diversity of the last chip */
+		dib8000_set_diversity_in(state->fe[index_frontend-1], 0);
+	} else {
+		dib8096p_set_output_mode(state->fe[0], state->cfg.output_mode);
+		if (state->cfg.enMpegOutput == 0) {
+			dib8096p_setDibTxMux(state, MPEG_ON_DIBTX);
+			dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
+		}
+		for (index_frontend = 1;
+				(index_frontend < MAX_NUMBER_OF_FRONTENDS) &&
+				(state->fe[index_frontend] != NULL);
+				index_frontend++) {
+			dib8096p_set_output_mode(state->fe[index_frontend],
+					OUTMODE_DIVERSITY);
+			dib8096p_set_diversity_in(state->fe[index_frontend-1], 1);
+		}
+
+		/* turn off the diversity of the last chip */
+		dib8096p_set_diversity_in(state->fe[index_frontend-1], 0);
+	}
 
 	return ret;
 }
@@ -2284,15 +3134,22 @@
 {
 	struct dib8000_state *state = fe->demodulator_priv;
 
+	if (state->revision == 0x8090)
+		return dib8000_read_word(state, 570);
 	return dib8000_read_word(state, 568);
 }
 
 static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
 {
 	struct dib8000_state *state = fe->demodulator_priv;
-	u16 lock_slave = 0, lock = dib8000_read_word(state, 568);
+	u16 lock_slave = 0, lock;
 	u8 index_frontend;
 
+	if (state->revision == 0x8090)
+		lock = dib8000_read_word(state, 570);
+	else
+		lock = dib8000_read_word(state, 568);
+
 	for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
 		lock_slave |= dib8000_read_lock(state->fe[index_frontend]);
 
@@ -2330,14 +3187,26 @@
 static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
 {
 	struct dib8000_state *state = fe->demodulator_priv;
-	*ber = (dib8000_read_word(state, 560) << 16) | dib8000_read_word(state, 561);	// 13 segments
+
+	/* 13 segments */
+	if (state->revision == 0x8090)
+		*ber = (dib8000_read_word(state, 562) << 16) |
+			dib8000_read_word(state, 563);
+	else
+		*ber = (dib8000_read_word(state, 560) << 16) |
+			dib8000_read_word(state, 561);
 	return 0;
 }
 
 static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
 {
 	struct dib8000_state *state = fe->demodulator_priv;
-	*unc = dib8000_read_word(state, 565);	// packet error on 13 seg
+
+	/* packet error on 13 seg */
+	if (state->revision == 0x8090)
+		*unc = dib8000_read_word(state, 567);
+	else
+		*unc = dib8000_read_word(state, 565);
 	return 0;
 }
 
@@ -2370,14 +3239,20 @@
 	u32 n, s, exp;
 	u16 val;
 
-	val = dib8000_read_word(state, 542);
+	if (state->revision != 0x8090)
+		val = dib8000_read_word(state, 542);
+	else
+		val = dib8000_read_word(state, 544);
 	n = (val >> 6) & 0xff;
 	exp = (val & 0x3f);
 	if ((exp & 0x20) != 0)
 		exp -= 0x40;
 	n <<= exp+16;
 
-	val = dib8000_read_word(state, 543);
+	if (state->revision != 0x8090)
+		val = dib8000_read_word(state, 543);
+	else
+		val = dib8000_read_word(state, 545);
 	s = (val >> 6) & 0xff;
 	exp = (val & 0x3f);
 	if ((exp & 0x20) != 0)
@@ -2401,7 +3276,7 @@
 	for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
 		snr_master += dib8000_get_snr(state->fe[index_frontend]);
 
-	if (snr_master != 0) {
+	if ((snr_master >> 16) != 0) {
 		snr_master = 10*intlog10(snr_master>>16);
 		*snr = snr_master / ((1 << 24) / 10);
 	}
@@ -2458,7 +3333,8 @@
 EXPORT_SYMBOL(dib8000_get_slave_frontend);
 
 
-int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
+int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods,
+		u8 default_addr, u8 first_addr, u8 is_dib8096p)
 {
 	int k = 0, ret = 0;
 	u8 new_addr = 0;
@@ -2488,9 +3364,12 @@
 		new_addr = first_addr + (k << 1);
 
 		client.addr = new_addr;
-		dib8000_i2c_write16(&client, 1287, 0x0003);	/* sram lead in, rdy */
-		if (dib8000_identify(&client) == 0) {
+		if (!is_dib8096p)
 			dib8000_i2c_write16(&client, 1287, 0x0003);	/* sram lead in, rdy */
+		if (dib8000_identify(&client) == 0) {
+			/* sram lead in, rdy */
+			if (!is_dib8096p)
+				dib8000_i2c_write16(&client, 1287, 0x0003);
 			client.addr = default_addr;
 			if (dib8000_identify(&client) == 0) {
 				dprintk("#%d: not identified", k);
@@ -2549,6 +3428,7 @@
 		dvb_frontend_detach(st->fe[index_frontend]);
 
 	dibx000_exit_i2c_master(&st->i2c_master);
+	i2c_del_adapter(&st->dib8096p_tuner_adap);
 	kfree(st->fe[0]);
 	kfree(st);
 }
@@ -2651,6 +3531,15 @@
 
 	dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
 
+	/* init 8096p tuner adapter */
+	strncpy(state->dib8096p_tuner_adap.name, "DiB8096P tuner interface",
+			sizeof(state->dib8096p_tuner_adap.name));
+	state->dib8096p_tuner_adap.algo = &dib8096p_tuner_xfer_algo;
+	state->dib8096p_tuner_adap.algo_data = NULL;
+	state->dib8096p_tuner_adap.dev.parent = state->i2c.adap->dev.parent;
+	i2c_set_adapdata(&state->dib8096p_tuner_adap, state);
+	i2c_add_adapter(&state->dib8096p_tuner_adap);
+
 	dib8000_reset(fe);
 
 	dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5));	/* ber_rs_len = 3 */
diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h
index 617f9eb..39591bb 100644
--- a/drivers/media/dvb/frontends/dib8000.h
+++ b/drivers/media/dvb/frontends/dib8000.h
@@ -32,6 +32,7 @@
 	u8 div_cfg;
 	u8 output_mode;
 	u8 refclksel;
+	u8 enMpegOutput:1;
 };
 
 #define DEFAULT_DIB8000_I2C_ADDRESS 18
@@ -40,7 +41,8 @@
 extern struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg);
 extern struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
 
-extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr);
+extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods,
+		u8 default_addr, u8 first_addr, u8 is_dib8096p);
 
 extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
 extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value);
@@ -50,6 +52,13 @@
 extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe);
 extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe);
 extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode);
+extern struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe);
+extern int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff);
+extern int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ);
+extern u32 dib8000_ctrl_timf(struct dvb_frontend *fe,
+		uint8_t op, uint32_t timf);
+extern int dib8000_update_pll(struct dvb_frontend *fe,
+		struct dibx000_bandwidth_config *pll);
 extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
 extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe);
 extern struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index);
@@ -66,7 +75,9 @@
 	return NULL;
 }
 
-static inline int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
+static inline int dib8000_i2c_enumeration(struct i2c_adapter *host,
+		int no_of_demods, u8 default_addr, u8 first_addr,
+		u8 is_dib8096p)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return -ENODEV;
@@ -109,11 +120,38 @@
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 }
+static inline struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+static inline int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return 0;
+}
 static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return 0;
 }
+static inline int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return 0;
+}
+static inline u32 dib8000_ctrl_timf(struct dvb_frontend *fe,
+		uint8_t op, uint32_t timf)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return 0;
+}
+static inline int dib8000_update_pll(struct dvb_frontend *fe,
+		struct dibx000_bandwidth_config *pll)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
 static inline int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h
index 5e01147..02e6431 100644
--- a/drivers/media/dvb/frontends/dibx000_common.h
+++ b/drivers/media/dvb/frontends/dibx000_common.h
@@ -276,4 +276,11 @@
 #define DEMOD_TIMF_GET    0x01
 #define DEMOD_TIMF_UPDATE 0x02
 
+#define MPEG_ON_DIBTX		1
+#define DIV_ON_DIBTX		2
+#define ADC_ON_DIBTX		3
+#define DEMOUT_ON_HOSTBUS	4
+#define DIBTX_ON_HOSTBUS	5
+#define MPEG_ON_HOSTBUS		6
+
 #endif
diff --git a/drivers/media/dvb/frontends/drxd_hard.c b/drivers/media/dvb/frontends/drxd_hard.c
index 88e46f4..beb6775 100644
--- a/drivers/media/dvb/frontends/drxd_hard.c
+++ b/drivers/media/dvb/frontends/drxd_hard.c
@@ -914,14 +914,13 @@
 		return -EIO;
 	}
 
-	state->microcode = kmalloc(fw->size, GFP_KERNEL);
+	state->microcode = kmemdup(fw->data, fw->size, GFP_KERNEL);
 	if (state->microcode == NULL) {
 		release_firmware(fw);
 		printk(KERN_ERR "drxd: firmware load failure: no memory\n");
 		return -ENOMEM;
 	}
 
-	memcpy(state->microcode, fw->data, fw->size);
 	state->microcode_length = fw->size;
 	release_firmware(fw);
 	return 0;
diff --git a/drivers/media/dvb/frontends/drxk.h b/drivers/media/dvb/frontends/drxk.h
index 58baf41..e6d42e2 100644
--- a/drivers/media/dvb/frontends/drxk.h
+++ b/drivers/media/dvb/frontends/drxk.h
@@ -26,6 +26,8 @@
 	bool	antenna_dvbt;
 	u16	antenna_gpio;
 
+	int    chunk_size;
+
 	const char *microcode_name;
 };
 
diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c
index f6431ef..d795898 100644
--- a/drivers/media/dvb/frontends/drxk_hard.c
+++ b/drivers/media/dvb/frontends/drxk_hard.c
@@ -681,7 +681,8 @@
 	state->m_hasOOB = false;
 	state->m_hasAudio = false;
 
-	state->m_ChunkSize = 124;
+	if (!state->m_ChunkSize)
+		state->m_ChunkSize = 124;
 
 	state->m_oscClockFreq = 0;
 	state->m_smartAntInverted = false;
@@ -1846,6 +1847,7 @@
 		*/
 	switch (oMode) {
 	case OM_DVBT:
+		dprintk(1, ": DVB-T\n");
 		state->m_OperationMode = oMode;
 		status = SetDVBTStandard(state, oMode);
 		if (status < 0)
@@ -1853,6 +1855,8 @@
 		break;
 	case OM_QAM_ITU_A:	/* fallthrough */
 	case OM_QAM_ITU_C:
+		dprintk(1, ": DVB-C Annex %c\n",
+			(state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C');
 		state->m_OperationMode = oMode;
 		status = SetQAMStandard(state, oMode);
 		if (status < 0)
@@ -6182,7 +6186,10 @@
 	dprintk(1, "\n");
 	if (mutex_trylock(&state->ctlock) == 0)
 		return -EBUSY;
-	SetOperationMode(state, OM_QAM_ITU_A);
+	if (state->m_itut_annex_c)
+		SetOperationMode(state, OM_QAM_ITU_C);
+	else
+		SetOperationMode(state, OM_QAM_ITU_A);
 	return 0;
 }
 
@@ -6208,6 +6215,7 @@
 			       struct dvb_frontend_parameters *p)
 {
 	struct drxk_state *state = fe->demodulator_priv;
+	u32 delsys  = fe->dtv_property_cache.delivery_system;
 	u32 IF;
 
 	dprintk(1, "\n");
@@ -6218,6 +6226,16 @@
 		return -EINVAL;
 	}
 
+	switch (delsys) {
+	case SYS_DVBC_ANNEX_A:
+		state->m_itut_annex_c = false;
+		break;
+	case SYS_DVBC_ANNEX_C:
+		state->m_itut_annex_c = true;
+		break;
+	default:
+		return -EINVAL;
+	}
 
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
@@ -6346,6 +6364,32 @@
 	return 0;
 }
 
+static int drxk_c_get_property(struct dvb_frontend *fe, struct dtv_property *p)
+{
+	switch (p->cmd) {
+	case DTV_ENUM_DELSYS:
+		p->u.buffer.data[0] = SYS_DVBC_ANNEX_A;
+		p->u.buffer.data[1] = SYS_DVBC_ANNEX_C;
+		p->u.buffer.len = 2;
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+static int drxk_t_get_property(struct dvb_frontend *fe, struct dtv_property *p)
+{
+	switch (p->cmd) {
+	case DTV_ENUM_DELSYS:
+		p->u.buffer.data[0] = SYS_DVBT;
+		p->u.buffer.len = 1;
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
 static struct dvb_frontend_ops drxk_c_ops = {
 	.info = {
 		 .name = "DRXK DVB-C",
@@ -6364,6 +6408,7 @@
 
 	.set_frontend = drxk_set_parameters,
 	.get_frontend = drxk_c_get_frontend,
+	.get_property = drxk_c_get_property,
 	.get_tune_settings = drxk_c_get_tune_settings,
 
 	.read_status = drxk_read_status,
@@ -6396,6 +6441,7 @@
 
 	.set_frontend = drxk_set_parameters,
 	.get_frontend = drxk_t_get_frontend,
+	.get_property = drxk_t_get_property,
 
 	.read_status = drxk_read_status,
 	.read_ber = drxk_read_ber,
@@ -6423,6 +6469,7 @@
 	state->no_i2c_bridge = config->no_i2c_bridge;
 	state->antenna_gpio = config->antenna_gpio;
 	state->antenna_dvbt = config->antenna_dvbt;
+	state->m_ChunkSize = config->chunk_size;
 
 	/* NOTE: as more UIO bits will be used, add them to the mask */
 	state->UIO_mask = config->antenna_gpio;
diff --git a/drivers/media/dvb/frontends/drxk_hard.h b/drivers/media/dvb/frontends/drxk_hard.h
index a05c32e..85a423f 100644
--- a/drivers/media/dvb/frontends/drxk_hard.h
+++ b/drivers/media/dvb/frontends/drxk_hard.h
@@ -263,6 +263,8 @@
 	u8     m_TSDataStrength;
 	u8     m_TSClockkStrength;
 
+	bool   m_itut_annex_c;      /* If true, uses ITU-T DVB-C Annex C, instead of Annex A */
+
 	enum DRXMPEGStrWidth_t  m_widthSTR;    /**< MPEG start width */
 	u32    m_mpegTsStaticBitrate;          /**< Maximum bitrate in b/s in case
 						    static clockrate is selected */
diff --git a/drivers/media/dvb/frontends/it913x-fe-priv.h b/drivers/media/dvb/frontends/it913x-fe-priv.h
index 1c6fb4b..ad2b644 100644
--- a/drivers/media/dvb/frontends/it913x-fe-priv.h
+++ b/drivers/media/dvb/frontends/it913x-fe-priv.h
@@ -153,8 +153,7 @@
 };
 
 static struct table fe_clockTable[] = {
-		{12000000, tab3},	/* FPGA     */
-		{16384000, tab6},	/* 16.38MHz */
+		{12000000, tab3},	/* 12.00MHz */
 		{20480000, tab6},	/* 20.48MHz */
 		{36000000, tab3},	/* 36.00MHz */
 		{30000000, tab1},	/* 30.00MHz */
@@ -164,7 +163,6 @@
 		{34000000, tab2},	/* 34.00MHz */
 		{24000000, tab1},	/* 24.00MHz */
 		{22000000, tab8},	/* 22.00MHz */
-		{12000000, tab3}	/* 12.00MHz */
 };
 
 /* fe get */
@@ -205,6 +203,10 @@
 
 /* Standard demodulator functions */
 static struct it913xset set_solo_fe[] = {
+	{PRO_LINK, GPIOH5_EN, {0x01}, 0x01},
+	{PRO_LINK, GPIOH5_ON, {0x01}, 0x01},
+	{PRO_LINK, GPIOH5_O, {0x00}, 0x01},
+	{PRO_LINK, GPIOH5_O, {0x01}, 0x01},
 	{PRO_LINK, DVBT_INTEN, {0x04}, 0x01},
 	{PRO_LINK, DVBT_ENABLE, {0x05}, 0x01},
 	{PRO_DMOD, MP2IF_MPEG_PAR_MODE, {0x00}, 0x01},
@@ -228,13 +230,127 @@
 	{PRO_LINK, LOCK3_OUT, {0x01}, 0x01},
 	{PRO_LINK, PADMISCDRSR, {0x01}, 0x01},
 	{PRO_LINK, PADMISCDR2, {0x00}, 0x01},
+	{PRO_DMOD, 0xec57, {0x00, 0x00}, 0x02},
 	{PRO_LINK, PADMISCDR4, {0x00}, 0x01}, /* Power up */
 	{PRO_LINK, PADMISCDR8, {0x00}, 0x01},
 	{0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
 };
 
-/* ---------IT9137 0x38 tuner init---------- */
-static struct it913xset it9137_set[] = {
+
+/* Version 1 types */
+static struct it913xset it9135_v1[] = {
+	{PRO_DMOD, 0x0051, {0x01}, 0x01},
+	{PRO_DMOD, 0x0070, {0x0a}, 0x01},
+	{PRO_DMOD, 0x007e, {0x04}, 0x01},
+	{PRO_DMOD, 0x0081, {0x0a}, 0x01},
+	{PRO_DMOD, 0x008a, {0x01}, 0x01},
+	{PRO_DMOD, 0x008e, {0x01}, 0x01},
+	{PRO_DMOD, 0x0092, {0x06}, 0x01},
+	{PRO_DMOD, 0x0099, {0x01}, 0x01},
+	{PRO_DMOD, 0x009f, {0xe1}, 0x01},
+	{PRO_DMOD, 0x00a0, {0xcf}, 0x01},
+	{PRO_DMOD, 0x00a3, {0x01}, 0x01},
+	{PRO_DMOD, 0x00a5, {0x01}, 0x01},
+	{PRO_DMOD, 0x00a6, {0x01}, 0x01},
+	{PRO_DMOD, 0x00a9, {0x00}, 0x01},
+	{PRO_DMOD, 0x00aa, {0x01}, 0x01},
+	{PRO_DMOD, 0x00b0, {0x01}, 0x01},
+	{PRO_DMOD, 0x00c2, {0x05}, 0x01},
+	{PRO_DMOD, 0x00c6, {0x19}, 0x01},
+	{PRO_DMOD, 0xf000, {0x0f}, 0x01},
+	{PRO_DMOD, 0xf016, {0x10}, 0x01},
+	{PRO_DMOD, 0xf017, {0x04}, 0x01},
+	{PRO_DMOD, 0xf018, {0x05}, 0x01},
+	{PRO_DMOD, 0xf019, {0x04}, 0x01},
+	{PRO_DMOD, 0xf01a, {0x05}, 0x01},
+	{PRO_DMOD, 0xf021, {0x03}, 0x01},
+	{PRO_DMOD, 0xf022, {0x0a}, 0x01},
+	{PRO_DMOD, 0xf023, {0x0a}, 0x01},
+	{PRO_DMOD, 0xf02b, {0x00}, 0x01},
+	{PRO_DMOD, 0xf02c, {0x01}, 0x01},
+	{PRO_DMOD, 0xf064, {0x03}, 0x01},
+	{PRO_DMOD, 0xf065, {0xf9}, 0x01},
+	{PRO_DMOD, 0xf066, {0x03}, 0x01},
+	{PRO_DMOD, 0xf067, {0x01}, 0x01},
+	{PRO_DMOD, 0xf06f, {0xe0}, 0x01},
+	{PRO_DMOD, 0xf070, {0x03}, 0x01},
+	{PRO_DMOD, 0xf072, {0x0f}, 0x01},
+	{PRO_DMOD, 0xf073, {0x03}, 0x01},
+	{PRO_DMOD, 0xf078, {0x00}, 0x01},
+	{PRO_DMOD, 0xf087, {0x00}, 0x01},
+	{PRO_DMOD, 0xf09b, {0x3f}, 0x01},
+	{PRO_DMOD, 0xf09c, {0x00}, 0x01},
+	{PRO_DMOD, 0xf09d, {0x20}, 0x01},
+	{PRO_DMOD, 0xf09e, {0x00}, 0x01},
+	{PRO_DMOD, 0xf09f, {0x0c}, 0x01},
+	{PRO_DMOD, 0xf0a0, {0x00}, 0x01},
+	{PRO_DMOD, 0xf130, {0x04}, 0x01},
+	{PRO_DMOD, 0xf132, {0x04}, 0x01},
+	{PRO_DMOD, 0xf144, {0x1a}, 0x01},
+	{PRO_DMOD, 0xf146, {0x00}, 0x01},
+	{PRO_DMOD, 0xf14a, {0x01}, 0x01},
+	{PRO_DMOD, 0xf14c, {0x00}, 0x01},
+	{PRO_DMOD, 0xf14d, {0x00}, 0x01},
+	{PRO_DMOD, 0xf14f, {0x04}, 0x01},
+	{PRO_DMOD, 0xf158, {0x7f}, 0x01},
+	{PRO_DMOD, 0xf15a, {0x00}, 0x01},
+	{PRO_DMOD, 0xf15b, {0x08}, 0x01},
+	{PRO_DMOD, 0xf15d, {0x03}, 0x01},
+	{PRO_DMOD, 0xf15e, {0x05}, 0x01},
+	{PRO_DMOD, 0xf163, {0x05}, 0x01},
+	{PRO_DMOD, 0xf166, {0x01}, 0x01},
+	{PRO_DMOD, 0xf167, {0x40}, 0x01},
+	{PRO_DMOD, 0xf168, {0x0f}, 0x01},
+	{PRO_DMOD, 0xf17a, {0x00}, 0x01},
+	{PRO_DMOD, 0xf17b, {0x00}, 0x01},
+	{PRO_DMOD, 0xf183, {0x01}, 0x01},
+	{PRO_DMOD, 0xf19d, {0x40}, 0x01},
+	{PRO_DMOD, 0xf1bc, {0x36}, 0x01},
+	{PRO_DMOD, 0xf1bd, {0x00}, 0x01},
+	{PRO_DMOD, 0xf1cb, {0xa0}, 0x01},
+	{PRO_DMOD, 0xf1cc, {0x01}, 0x01},
+	{PRO_DMOD, 0xf204, {0x10}, 0x01},
+	{PRO_DMOD, 0xf214, {0x00}, 0x01},
+	{PRO_DMOD, 0xf40e, {0x0a}, 0x01},
+	{PRO_DMOD, 0xf40f, {0x40}, 0x01},
+	{PRO_DMOD, 0xf410, {0x08}, 0x01},
+	{PRO_DMOD, 0xf55f, {0x0a}, 0x01},
+	{PRO_DMOD, 0xf561, {0x15}, 0x01},
+	{PRO_DMOD, 0xf562, {0x20}, 0x01},
+	{PRO_DMOD, 0xf5df, {0xfb}, 0x01},
+	{PRO_DMOD, 0xf5e0, {0x00}, 0x01},
+	{PRO_DMOD, 0xf5e3, {0x09}, 0x01},
+	{PRO_DMOD, 0xf5e4, {0x01}, 0x01},
+	{PRO_DMOD, 0xf5e5, {0x01}, 0x01},
+	{PRO_DMOD, 0xf5f8, {0x01}, 0x01},
+	{PRO_DMOD, 0xf5fd, {0x01}, 0x01},
+	{PRO_DMOD, 0xf600, {0x05}, 0x01},
+	{PRO_DMOD, 0xf601, {0x08}, 0x01},
+	{PRO_DMOD, 0xf602, {0x0b}, 0x01},
+	{PRO_DMOD, 0xf603, {0x0e}, 0x01},
+	{PRO_DMOD, 0xf604, {0x11}, 0x01},
+	{PRO_DMOD, 0xf605, {0x14}, 0x01},
+	{PRO_DMOD, 0xf606, {0x17}, 0x01},
+	{PRO_DMOD, 0xf607, {0x1f}, 0x01},
+	{PRO_DMOD, 0xf60e, {0x00}, 0x01},
+	{PRO_DMOD, 0xf60f, {0x04}, 0x01},
+	{PRO_DMOD, 0xf610, {0x32}, 0x01},
+	{PRO_DMOD, 0xf611, {0x10}, 0x01},
+	{PRO_DMOD, 0xf707, {0xfc}, 0x01},
+	{PRO_DMOD, 0xf708, {0x00}, 0x01},
+	{PRO_DMOD, 0xf709, {0x37}, 0x01},
+	{PRO_DMOD, 0xf70a, {0x00}, 0x01},
+	{PRO_DMOD, 0xf78b, {0x01}, 0x01},
+	{PRO_DMOD, 0xf80f, {0x40}, 0x01},
+	{PRO_DMOD, 0xf810, {0x54}, 0x01},
+	{PRO_DMOD, 0xf811, {0x5a}, 0x01},
+	{PRO_DMOD, 0xf905, {0x01}, 0x01},
+	{PRO_DMOD, 0xfb06, {0x03}, 0x01},
+	{PRO_DMOD, 0xfd8b, {0x00}, 0x01},
+	{0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
+};
+
+static struct it913xset it9135_38[] = {
 	{PRO_DMOD, 0x0043, {0x00}, 0x01},
 	{PRO_DMOD, 0x0046, {0x38}, 0x01},
 	{PRO_DMOD, 0x0051, {0x01}, 0x01},
@@ -244,7 +360,7 @@
 	{PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xc8, 0x01}, 0x05},
 	{PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02},
 	{PRO_DMOD, 0x0081, {	0x0a, 0x12, 0x02, 0x0a, 0x03, 0xc8, 0xb8,
-				0xd0, 0xc3, 0x01	}, 0x0a},
+				0xd0, 0xc3, 0x01}, 0x0a},
 	{PRO_DMOD, 0x008e, {0x01}, 0x01},
 	{PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
 	{PRO_DMOD, 0x0099, {0x01}, 0x01},
@@ -262,15 +378,25 @@
 	{PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03},
 	{PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
 	{PRO_DMOD, 0x00fc, {	0x02, 0x02, 0x02, 0x09, 0x50, 0x7b, 0x77,
-				0x00, 0x02, 0xc8, 0x05, 0x7b	}, 0x0c},
+				0x00, 0x02, 0xc8, 0x05, 0x7b}, 0x0c},
 	{PRO_DMOD, 0x0109, {0x02}, 0x01},
-	{PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02},
-	{PRO_DMOD, 0x011a, {0xc8, 0x7b, 0xbc, 0xa0}, 0x04},
+	{PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04},
+	{PRO_DMOD, 0x011a, {0xc8, 0x7b, 0x8a, 0xa0}, 0x04},
 	{PRO_DMOD, 0x0122, {0x02, 0x18, 0xc3}, 0x03},
 	{PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02},
 	{PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04},
 	{PRO_DMOD, 0x0137, {0x01, 0x00, 0x07, 0x00, 0x06}, 0x05},
-	{PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xc8}, 0x04},
+	{PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xc8, 0x59}, 0x05},
+	{PRO_DMOD, 0xf000, {0x0f}, 0x01},
+	{PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05},
+	{PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05},
+	{PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04},
+	{PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
+	{PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
+	{PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
+	{PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
+	{PRO_DMOD, 0xf085, {0x00, 0x02, 0x00}, 0x03},
+	{PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
 	{PRO_DMOD, 0xf130, {0x04}, 0x01},
 	{PRO_DMOD, 0xf132, {0x04}, 0x01},
 	{PRO_DMOD, 0xf144, {0x1a}, 0x01},
@@ -301,7 +427,7 @@
 	{PRO_DMOD, 0xf5f8, {0x01}, 0x01},
 	{PRO_DMOD, 0xf5fd, {0x01}, 0x01},
 	{PRO_DMOD, 0xf600, {	0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
-				0x1f	}, 0x08},
+				0x1f}, 0x08},
 	{PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
 	{PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
 	{PRO_DMOD, 0xf78b, {0x01}, 0x01},
@@ -309,21 +435,605 @@
 	{PRO_DMOD, 0xf905, {0x01}, 0x01},
 	{PRO_DMOD, 0xfb06, {0x03}, 0x01},
 	{PRO_DMOD, 0xfd8b, {0x00}, 0x01},
-	{PRO_LINK, GPIOH5_EN, {0x01}, 0x01},
-	{PRO_LINK, GPIOH5_ON, {0x01}, 0x01},
-	{PRO_LINK, GPIOH5_O, {0x00}, 0x01},
-	{PRO_LINK, GPIOH5_O, {0x01}, 0x01},
-	{0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */
+	{0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
 };
 
+static struct it913xset it9135_51[] = {
+	{PRO_DMOD, 0x0043, {0x00}, 0x01},
+	{PRO_DMOD, 0x0046, {0x51}, 0x01},
+	{PRO_DMOD, 0x0051, {0x01}, 0x01},
+	{PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
+	{PRO_DMOD, 0x0068, {0x0a}, 0x01},
+	{PRO_DMOD, 0x0070, {0x0a, 0x06, 0x02}, 0x03},
+	{PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xc8, 0x01}, 0x05},
+	{PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02},
+	{PRO_DMOD, 0x0081, {	0x0a, 0x12, 0x02, 0x0a, 0x03, 0xc0, 0x96,
+				0xcf, 0xc3, 0x01}, 0x0a},
+	{PRO_DMOD, 0x008e, {0x01}, 0x01},
+	{PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
+	{PRO_DMOD, 0x0099, {0x01}, 0x01},
+	{PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
+	{PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
+	{PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04},
+	{PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
+	{PRO_DMOD, 0x00b0, {0x01}, 0x01},
+	{PRO_DMOD, 0x00b3, {0x02, 0x3c}, 0x02},
+	{PRO_DMOD, 0x00b6, {0x14}, 0x01},
+	{PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05}, 0x03},
+	{PRO_DMOD, 0x00c4, {0x00}, 0x01},
+	{PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
+	{PRO_DMOD, 0x00cc, {0x2e, 0x51, 0x33}, 0x03},
+	{PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03},
+	{PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
+	{PRO_DMOD, 0x00fc, {	0x03, 0x02, 0x02, 0x09, 0x50, 0x7a, 0x77,
+				0x01, 0x02, 0xb0, 0x02, 0x7a}, 0x0c},
+	{PRO_DMOD, 0x0109, {0x02}, 0x01},
+	{PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04},
+	{PRO_DMOD, 0x011a, {0xc0, 0x7a, 0xac, 0x8c}, 0x04},
+	{PRO_DMOD, 0x0122, {0x02, 0x70, 0xa4}, 0x03},
+	{PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02},
+	{PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04},
+	{PRO_DMOD, 0x0137, {0x01, 0x00, 0x07, 0x00, 0x06}, 0x05},
+	{PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xc0, 0x59}, 0x05},
+	{PRO_DMOD, 0xf000, {0x0f}, 0x01},
+	{PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05},
+	{PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05},
+	{PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04},
+	{PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
+	{PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
+	{PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
+	{PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
+	{PRO_DMOD, 0xf085, {0xc0, 0x01, 0x00}, 0x03},
+	{PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
+	{PRO_DMOD, 0xf130, {0x04}, 0x01},
+	{PRO_DMOD, 0xf132, {0x04}, 0x01},
+	{PRO_DMOD, 0xf144, {0x1a}, 0x01},
+	{PRO_DMOD, 0xf146, {0x00}, 0x01},
+	{PRO_DMOD, 0xf14a, {0x01}, 0x01},
+	{PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
+	{PRO_DMOD, 0xf14f, {0x04}, 0x01},
+	{PRO_DMOD, 0xf158, {0x7f}, 0x01},
+	{PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
+	{PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
+	{PRO_DMOD, 0xf163, {0x05}, 0x01},
+	{PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
+	{PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
+	{PRO_DMOD, 0xf183, {0x01}, 0x01},
+	{PRO_DMOD, 0xf19d, {0x40}, 0x01},
+	{PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
+	{PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
+	{PRO_DMOD, 0xf204, {0x10}, 0x01},
+	{PRO_DMOD, 0xf214, {0x00}, 0x01},
+	{PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
+	{PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
+	{PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
+	{PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
+	{PRO_DMOD, 0xf55f, {0x0a}, 0x01},
+	{PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
+	{PRO_DMOD, 0xf5df, {0xfb, 0x00}, 0x02},
+	{PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
+	{PRO_DMOD, 0xf5f8, {0x01}, 0x01},
+	{PRO_DMOD, 0xf5fd, {0x01}, 0x01},
+	{PRO_DMOD, 0xf600, {	0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
+				0x1f}, 0x08},
+	{PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
+	{PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
+	{PRO_DMOD, 0xf78b, {0x01}, 0x01},
+	{PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
+	{PRO_DMOD, 0xf905, {0x01}, 0x01},
+	{PRO_DMOD, 0xfb06, {0x03}, 0x01},
+	{PRO_DMOD, 0xfd8b, {0x00}, 0x01},
+	{0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
+};
+
+static struct it913xset it9135_52[] = {
+	{PRO_DMOD, 0x0043, {0x00}, 0x01},
+	{PRO_DMOD, 0x0046, {0x52}, 0x01},
+	{PRO_DMOD, 0x0051, {0x01}, 0x01},
+	{PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
+	{PRO_DMOD, 0x0068, {0x10}, 0x01},
+	{PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03},
+	{PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0xa0, 0x01}, 0x05},
+	{PRO_DMOD, 0x007e, {0x04, 0x00}, 0x02},
+	{PRO_DMOD, 0x0081, {	0x0a, 0x12, 0x03, 0x0a, 0x03, 0xb3, 0x97,
+				0xc0, 0x9e, 0x01}, 0x0a},
+	{PRO_DMOD, 0x008e, {0x01}, 0x01},
+	{PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
+	{PRO_DMOD, 0x0099, {0x01}, 0x01},
+	{PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
+	{PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
+	{PRO_DMOD, 0x00a3, {0x01, 0x5c, 0x01, 0x01}, 0x04},
+	{PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
+	{PRO_DMOD, 0x00b0, {0x01}, 0x01},
+	{PRO_DMOD, 0x00b3, {0x02, 0x3c}, 0x02},
+	{PRO_DMOD, 0x00b6, {0x14}, 0x01},
+	{PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05}, 0x03},
+	{PRO_DMOD, 0x00c4, {0x00}, 0x01},
+	{PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
+	{PRO_DMOD, 0x00cc, {0x2e, 0x51, 0x33}, 0x03},
+	{PRO_DMOD, 0x00f3, {0x05, 0x91, 0x8c}, 0x03},
+	{PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
+	{PRO_DMOD, 0x00fc, {	0x03, 0x02, 0x02, 0x09, 0x50, 0x74, 0x77,
+				0x02, 0x02, 0xae, 0x02, 0x6e}, 0x0c},
+	{PRO_DMOD, 0x0109, {0x02}, 0x01},
+	{PRO_DMOD, 0x0115, {0x0a, 0x03, 0x02, 0x80}, 0x04},
+	{PRO_DMOD, 0x011a, {0xcd, 0x62, 0xa4, 0x8c}, 0x04},
+	{PRO_DMOD, 0x0122, {0x03, 0x18, 0x9e}, 0x03},
+	{PRO_DMOD, 0x0127, {0x00, 0x07}, 0x02},
+	{PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04},
+	{PRO_DMOD, 0x0137, {0x00, 0x00, 0x07, 0x00, 0x06}, 0x05},
+	{PRO_DMOD, 0x013d, {0x00, 0x01, 0x5b, 0xb6, 0x59}, 0x05},
+	{PRO_DMOD, 0xf000, {0x0f}, 0x01},
+	{PRO_DMOD, 0xf016, {0x10, 0x04, 0x05, 0x04, 0x05}, 0x05},
+	{PRO_DMOD, 0xf01f, {0x8c, 0x00, 0x03, 0x0a, 0x0a}, 0x05},
+	{PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00, 0x01}, 0x04},
+	{PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
+	{PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
+	{PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
+	{PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
+	{PRO_DMOD, 0xf085, {0xc0, 0x01, 0x00}, 0x03},
+	{PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
+	{PRO_DMOD, 0xf130, {0x04}, 0x01},
+	{PRO_DMOD, 0xf132, {0x04}, 0x01},
+	{PRO_DMOD, 0xf144, {0x1a}, 0x01},
+	{PRO_DMOD, 0xf146, {0x00}, 0x01},
+	{PRO_DMOD, 0xf14a, {0x01}, 0x01},
+	{PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
+	{PRO_DMOD, 0xf14f, {0x04}, 0x01},
+	{PRO_DMOD, 0xf158, {0x7f}, 0x01},
+	{PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
+	{PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
+	{PRO_DMOD, 0xf163, {0x05}, 0x01},
+	{PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
+	{PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
+	{PRO_DMOD, 0xf183, {0x01}, 0x01},
+	{PRO_DMOD, 0xf19d, {0x40}, 0x01},
+	{PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
+	{PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
+	{PRO_DMOD, 0xf204, {0x10}, 0x01},
+	{PRO_DMOD, 0xf214, {0x00}, 0x01},
+	{PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
+	{PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
+	{PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
+	{PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
+	{PRO_DMOD, 0xf55f, {0x0a}, 0x01},
+	{PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
+	{PRO_DMOD, 0xf5df, {0xfb, 0x00}, 0x02},
+	{PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
+	{PRO_DMOD, 0xf5f8, {0x01}, 0x01},
+	{PRO_DMOD, 0xf5fd, {0x01}, 0x01},
+	{PRO_DMOD, 0xf600, {0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
+				0x1f}, 0x08},
+	{PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
+	{PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
+	{PRO_DMOD, 0xf78b, {0x01}, 0x01},
+	{PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
+	{PRO_DMOD, 0xf905, {0x01}, 0x01},
+	{PRO_DMOD, 0xfb06, {0x03}, 0x01},
+	{PRO_DMOD, 0xfd8b, {0x00}, 0x01},
+	{0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
+};
+
+/* Version 2 types */
+static struct it913xset it9135_v2[] = {
+	{PRO_DMOD, 0x0051, {0x01}, 0x01},
+	{PRO_DMOD, 0x0070, {0x0a}, 0x01},
+	{PRO_DMOD, 0x007e, {0x04}, 0x01},
+	{PRO_DMOD, 0x0081, {0x0a}, 0x01},
+	{PRO_DMOD, 0x008a, {0x01}, 0x01},
+	{PRO_DMOD, 0x008e, {0x01}, 0x01},
+	{PRO_DMOD, 0x0092, {0x06}, 0x01},
+	{PRO_DMOD, 0x0099, {0x01}, 0x01},
+	{PRO_DMOD, 0x009f, {0xe1}, 0x01},
+	{PRO_DMOD, 0x00a0, {0xcf}, 0x01},
+	{PRO_DMOD, 0x00a3, {0x01}, 0x01},
+	{PRO_DMOD, 0x00a5, {0x01}, 0x01},
+	{PRO_DMOD, 0x00a6, {0x01}, 0x01},
+	{PRO_DMOD, 0x00a9, {0x00}, 0x01},
+	{PRO_DMOD, 0x00aa, {0x01}, 0x01},
+	{PRO_DMOD, 0x00b0, {0x01}, 0x01},
+	{PRO_DMOD, 0x00c2, {0x05}, 0x01},
+	{PRO_DMOD, 0x00c6, {0x19}, 0x01},
+	{PRO_DMOD, 0xf000, {0x0f}, 0x01},
+	{PRO_DMOD, 0xf02b, {0x00}, 0x01},
+	{PRO_DMOD, 0xf064, {0x03}, 0x01},
+	{PRO_DMOD, 0xf065, {0xf9}, 0x01},
+	{PRO_DMOD, 0xf066, {0x03}, 0x01},
+	{PRO_DMOD, 0xf067, {0x01}, 0x01},
+	{PRO_DMOD, 0xf06f, {0xe0}, 0x01},
+	{PRO_DMOD, 0xf070, {0x03}, 0x01},
+	{PRO_DMOD, 0xf072, {0x0f}, 0x01},
+	{PRO_DMOD, 0xf073, {0x03}, 0x01},
+	{PRO_DMOD, 0xf078, {0x00}, 0x01},
+	{PRO_DMOD, 0xf087, {0x00}, 0x01},
+	{PRO_DMOD, 0xf09b, {0x3f}, 0x01},
+	{PRO_DMOD, 0xf09c, {0x00}, 0x01},
+	{PRO_DMOD, 0xf09d, {0x20}, 0x01},
+	{PRO_DMOD, 0xf09e, {0x00}, 0x01},
+	{PRO_DMOD, 0xf09f, {0x0c}, 0x01},
+	{PRO_DMOD, 0xf0a0, {0x00}, 0x01},
+	{PRO_DMOD, 0xf130, {0x04}, 0x01},
+	{PRO_DMOD, 0xf132, {0x04}, 0x01},
+	{PRO_DMOD, 0xf144, {0x1a}, 0x01},
+	{PRO_DMOD, 0xf146, {0x00}, 0x01},
+	{PRO_DMOD, 0xf14a, {0x01}, 0x01},
+	{PRO_DMOD, 0xf14c, {0x00}, 0x01},
+	{PRO_DMOD, 0xf14d, {0x00}, 0x01},
+	{PRO_DMOD, 0xf14f, {0x04}, 0x01},
+	{PRO_DMOD, 0xf158, {0x7f}, 0x01},
+	{PRO_DMOD, 0xf15a, {0x00}, 0x01},
+	{PRO_DMOD, 0xf15b, {0x08}, 0x01},
+	{PRO_DMOD, 0xf15d, {0x03}, 0x01},
+	{PRO_DMOD, 0xf15e, {0x05}, 0x01},
+	{PRO_DMOD, 0xf163, {0x05}, 0x01},
+	{PRO_DMOD, 0xf166, {0x01}, 0x01},
+	{PRO_DMOD, 0xf167, {0x40}, 0x01},
+	{PRO_DMOD, 0xf168, {0x0f}, 0x01},
+	{PRO_DMOD, 0xf17a, {0x00}, 0x01},
+	{PRO_DMOD, 0xf17b, {0x00}, 0x01},
+	{PRO_DMOD, 0xf183, {0x01}, 0x01},
+	{PRO_DMOD, 0xf19d, {0x40}, 0x01},
+	{PRO_DMOD, 0xf1bc, {0x36}, 0x01},
+	{PRO_DMOD, 0xf1bd, {0x00}, 0x01},
+	{PRO_DMOD, 0xf1cb, {0xa0}, 0x01},
+	{PRO_DMOD, 0xf1cc, {0x01}, 0x01},
+	{PRO_DMOD, 0xf204, {0x10}, 0x01},
+	{PRO_DMOD, 0xf214, {0x00}, 0x01},
+	{PRO_DMOD, 0xf40e, {0x0a}, 0x01},
+	{PRO_DMOD, 0xf40f, {0x40}, 0x01},
+	{PRO_DMOD, 0xf410, {0x08}, 0x01},
+	{PRO_DMOD, 0xf55f, {0x0a}, 0x01},
+	{PRO_DMOD, 0xf561, {0x15}, 0x01},
+	{PRO_DMOD, 0xf562, {0x20}, 0x01},
+	{PRO_DMOD, 0xf5e3, {0x09}, 0x01},
+	{PRO_DMOD, 0xf5e4, {0x01}, 0x01},
+	{PRO_DMOD, 0xf5e5, {0x01}, 0x01},
+	{PRO_DMOD, 0xf600, {0x05}, 0x01},
+	{PRO_DMOD, 0xf601, {0x08}, 0x01},
+	{PRO_DMOD, 0xf602, {0x0b}, 0x01},
+	{PRO_DMOD, 0xf603, {0x0e}, 0x01},
+	{PRO_DMOD, 0xf604, {0x11}, 0x01},
+	{PRO_DMOD, 0xf605, {0x14}, 0x01},
+	{PRO_DMOD, 0xf606, {0x17}, 0x01},
+	{PRO_DMOD, 0xf607, {0x1f}, 0x01},
+	{PRO_DMOD, 0xf60e, {0x00}, 0x01},
+	{PRO_DMOD, 0xf60f, {0x04}, 0x01},
+	{PRO_DMOD, 0xf610, {0x32}, 0x01},
+	{PRO_DMOD, 0xf611, {0x10}, 0x01},
+	{PRO_DMOD, 0xf707, {0xfc}, 0x01},
+	{PRO_DMOD, 0xf708, {0x00}, 0x01},
+	{PRO_DMOD, 0xf709, {0x37}, 0x01},
+	{PRO_DMOD, 0xf70a, {0x00}, 0x01},
+	{PRO_DMOD, 0xf78b, {0x01}, 0x01},
+	{PRO_DMOD, 0xf80f, {0x40}, 0x01},
+	{PRO_DMOD, 0xf810, {0x54}, 0x01},
+	{PRO_DMOD, 0xf811, {0x5a}, 0x01},
+	{PRO_DMOD, 0xf905, {0x01}, 0x01},
+	{PRO_DMOD, 0xfb06, {0x03}, 0x01},
+	{PRO_DMOD, 0xfd8b, {0x00}, 0x01},
+	{0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
+};
+
+static struct it913xset it9135_60[] = {
+	{PRO_DMOD, 0x0043, {0x00}, 0x01},
+	{PRO_DMOD, 0x0046, {0x60}, 0x01},
+	{PRO_DMOD, 0x0051, {0x01}, 0x01},
+	{PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
+	{PRO_DMOD, 0x0068, {0x0a}, 0x01},
+	{PRO_DMOD, 0x006a, {0x03}, 0x01},
+	{PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03},
+	{PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x8c, 0x01}, 0x05},
+	{PRO_DMOD, 0x007e, {0x04}, 0x01},
+	{PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02},
+	{PRO_DMOD, 0x0084, {0x0a, 0x33, 0xbe, 0xa0, 0xc6, 0xb6, 0x01}, 0x07},
+	{PRO_DMOD, 0x008e, {0x01}, 0x01},
+	{PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
+	{PRO_DMOD, 0x0099, {0x01}, 0x01},
+	{PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
+	{PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
+	{PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04},
+	{PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
+	{PRO_DMOD, 0x00b0, {0x01}, 0x01},
+	{PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02},
+	{PRO_DMOD, 0x00b6, {0x14}, 0x01},
+	{PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05},
+	{PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
+	{PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04},
+	{PRO_DMOD, 0x00f3, {0x05, 0xa0, 0x8c}, 0x03},
+	{PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
+	{PRO_DMOD, 0x00fc, {	0x03, 0x03, 0x02, 0x0a, 0x50, 0x7b, 0x8c,
+				0x00, 0x02, 0xbe, 0x00}, 0x0b},
+	{PRO_DMOD, 0x0109, {0x02}, 0x01},
+	{PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02},
+	{PRO_DMOD, 0x011a, {0xbe}, 0x01},
+	{PRO_DMOD, 0x0124, {0xae}, 0x01},
+	{PRO_DMOD, 0x0127, {0x00}, 0x01},
+	{PRO_DMOD, 0x012a, {0x56, 0x50, 0x47, 0x42}, 0x04},
+	{PRO_DMOD, 0x0137, {0x00}, 0x01},
+	{PRO_DMOD, 0x013b, {0x08}, 0x01},
+	{PRO_DMOD, 0x013f, {0x5b}, 0x01},
+	{PRO_DMOD, 0x0141, {	0x59, 0xf9, 0x19, 0x19, 0x8c, 0x8c, 0x8c,
+				0x6e, 0x8c, 0x50, 0x8c, 0x8c, 0xac, 0xc6,
+				0x33}, 0x0f},
+	{PRO_DMOD, 0x0151, {0x28}, 0x01},
+	{PRO_DMOD, 0x0153, {0xbc}, 0x01},
+	{PRO_DMOD, 0x0178, {0x09}, 0x01},
+	{PRO_DMOD, 0x0181, {0x94, 0x6e}, 0x02},
+	{PRO_DMOD, 0x0185, {0x24}, 0x01},
+	{PRO_DMOD, 0x0187, {0x00, 0x00, 0xbe, 0x02, 0x80}, 0x05},
+	{PRO_DMOD, 0xed02, {0xff}, 0x01},
+	{PRO_DMOD, 0xee42, {0xff}, 0x01},
+	{PRO_DMOD, 0xee82, {0xff}, 0x01},
+	{PRO_DMOD, 0xf000, {0x0f}, 0x01},
+	{PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02},
+	{PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03},
+	{PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
+	{PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
+	{PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
+	{PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
+	{PRO_DMOD, 0xf087, {0x00}, 0x01},
+	{PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
+	{PRO_DMOD, 0xf130, {0x04}, 0x01},
+	{PRO_DMOD, 0xf132, {0x04}, 0x01},
+	{PRO_DMOD, 0xf144, {0x1a}, 0x01},
+	{PRO_DMOD, 0xf146, {0x00}, 0x01},
+	{PRO_DMOD, 0xf14a, {0x01}, 0x01},
+	{PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
+	{PRO_DMOD, 0xf14f, {0x04}, 0x01},
+	{PRO_DMOD, 0xf158, {0x7f}, 0x01},
+	{PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
+	{PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
+	{PRO_DMOD, 0xf163, {0x05}, 0x01},
+	{PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
+	{PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
+	{PRO_DMOD, 0xf183, {0x01}, 0x01},
+	{PRO_DMOD, 0xf19d, {0x40}, 0x01},
+	{PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
+	{PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
+	{PRO_DMOD, 0xf204, {0x10}, 0x01},
+	{PRO_DMOD, 0xf214, {0x00}, 0x01},
+	{PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
+	{PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
+	{PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
+	{PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
+	{PRO_DMOD, 0xf55f, {0x0a}, 0x01},
+	{PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
+	{PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
+	{PRO_DMOD, 0xf600, {0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17
+		, 0x1f}, 0x08},
+	{PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
+	{PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
+	{PRO_DMOD, 0xf78b, {0x01}, 0x01},
+	{PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
+	{PRO_DMOD, 0xf905, {0x01}, 0x01},
+	{PRO_DMOD, 0xfb06, {0x03}, 0x01},
+	{PRO_DMOD, 0xfd8b, {0x00}, 0x01},
+	{0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
+};
+
+static struct it913xset it9135_61[] = {
+	{PRO_DMOD, 0x0043, {0x00}, 0x01},
+	{PRO_DMOD, 0x0046, {0x61}, 0x01},
+	{PRO_DMOD, 0x0051, {0x01}, 0x01},
+	{PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
+	{PRO_DMOD, 0x0068, {0x06}, 0x01},
+	{PRO_DMOD, 0x006a, {0x03}, 0x01},
+	{PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03},
+	{PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x90, 0x01}, 0x05},
+	{PRO_DMOD, 0x007e, {0x04}, 0x01},
+	{PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02},
+	{PRO_DMOD, 0x0084, {0x0a, 0x33, 0xbc, 0x9c, 0xcc, 0xa8, 0x01}, 0x07},
+	{PRO_DMOD, 0x008e, {0x01}, 0x01},
+	{PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
+	{PRO_DMOD, 0x0099, {0x01}, 0x01},
+	{PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
+	{PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
+	{PRO_DMOD, 0x00a3, {0x01, 0x5c, 0x01, 0x01}, 0x04},
+	{PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
+	{PRO_DMOD, 0x00b0, {0x01}, 0x01},
+	{PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02},
+	{PRO_DMOD, 0x00b6, {0x14}, 0x01},
+	{PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05},
+	{PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
+	{PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04},
+	{PRO_DMOD, 0x00f3, {0x05, 0xa0, 0x8c}, 0x03},
+	{PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
+	{PRO_DMOD, 0x00fc, {	0x03, 0x03, 0x02, 0x08, 0x50, 0x7b, 0x8c,
+				0x01, 0x02, 0xc8, 0x00}, 0x0b},
+	{PRO_DMOD, 0x0109, {0x02}, 0x01},
+	{PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02},
+	{PRO_DMOD, 0x011a, {0xc6}, 0x01},
+	{PRO_DMOD, 0x0124, {0xa8}, 0x01},
+	{PRO_DMOD, 0x0127, {0x00}, 0x01},
+	{PRO_DMOD, 0x012a, {0x59, 0x50, 0x47, 0x42}, 0x04},
+	{PRO_DMOD, 0x0137, {0x00}, 0x01},
+	{PRO_DMOD, 0x013b, {0x05}, 0x01},
+	{PRO_DMOD, 0x013f, {0x5b}, 0x01},
+	{PRO_DMOD, 0x0141, {	0x59, 0xf9, 0x59, 0x59, 0x8c, 0x8c, 0x8c,
+				0x7b, 0x8c, 0x50, 0x8c, 0x8c, 0xa8, 0xc6,
+				0x33}, 0x0f},
+	{PRO_DMOD, 0x0151, {0x28}, 0x01},
+	{PRO_DMOD, 0x0153, {0xcc}, 0x01},
+	{PRO_DMOD, 0x0178, {0x09}, 0x01},
+	{PRO_DMOD, 0x0181, {0x9c, 0x76}, 0x02},
+	{PRO_DMOD, 0x0185, {0x28}, 0x01},
+	{PRO_DMOD, 0x0187, {0x01, 0x00, 0xaa, 0x02, 0x80}, 0x05},
+	{PRO_DMOD, 0xed02, {0xff}, 0x01},
+	{PRO_DMOD, 0xee42, {0xff}, 0x01},
+	{PRO_DMOD, 0xee82, {0xff}, 0x01},
+	{PRO_DMOD, 0xf000, {0x0f}, 0x01},
+	{PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02},
+	{PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03},
+	{PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
+	{PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
+	{PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
+	{PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
+	{PRO_DMOD, 0xf087, {0x00}, 0x01},
+	{PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
+	{PRO_DMOD, 0xf130, {0x04}, 0x01},
+	{PRO_DMOD, 0xf132, {0x04}, 0x01},
+	{PRO_DMOD, 0xf144, {0x1a}, 0x01},
+	{PRO_DMOD, 0xf146, {0x00}, 0x01},
+	{PRO_DMOD, 0xf14a, {0x01}, 0x01},
+	{PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
+	{PRO_DMOD, 0xf14f, {0x04}, 0x01},
+	{PRO_DMOD, 0xf158, {0x7f}, 0x01},
+	{PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
+	{PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
+	{PRO_DMOD, 0xf163, {0x05}, 0x01},
+	{PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
+	{PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
+	{PRO_DMOD, 0xf183, {0x01}, 0x01},
+	{PRO_DMOD, 0xf19d, {0x40}, 0x01},
+	{PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
+	{PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
+	{PRO_DMOD, 0xf204, {0x10}, 0x01},
+	{PRO_DMOD, 0xf214, {0x00}, 0x01},
+	{PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
+	{PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
+	{PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
+	{PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
+	{PRO_DMOD, 0xf55f, {0x0a}, 0x01},
+	{PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
+	{PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
+	{PRO_DMOD, 0xf600, {	0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
+				0x1f}, 0x08},
+	{PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
+	{PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
+	{PRO_DMOD, 0xf78b, {0x01}, 0x01},
+	{PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
+	{PRO_DMOD, 0xf905, {0x01}, 0x01},
+	{PRO_DMOD, 0xfb06, {0x03}, 0x01},
+	{PRO_DMOD, 0xfd8b, {0x00}, 0x01},
+	{0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
+};
+
+static struct it913xset it9135_62[] = {
+	{PRO_DMOD, 0x0043, {0x00}, 0x01},
+	{PRO_DMOD, 0x0046, {0x62}, 0x01},
+	{PRO_DMOD, 0x0051, {0x01}, 0x01},
+	{PRO_DMOD, 0x005f, {0x00, 0x00}, 0x02},
+	{PRO_DMOD, 0x0068, {0x0a}, 0x01},
+	{PRO_DMOD, 0x006a, {0x03}, 0x01},
+	{PRO_DMOD, 0x0070, {0x0a, 0x05, 0x02}, 0x03},
+	{PRO_DMOD, 0x0075, {0x8c, 0x8c, 0x8c, 0x8c, 0x01}, 0x05},
+	{PRO_DMOD, 0x007e, {0x04}, 0x01},
+	{PRO_DMOD, 0x0081, {0x0a, 0x12}, 0x02},
+	{PRO_DMOD, 0x0084, {	0x0a, 0x33, 0xb8, 0x9c, 0xb2, 0xa6, 0x01},
+				0x07},
+	{PRO_DMOD, 0x008e, {0x01}, 0x01},
+	{PRO_DMOD, 0x0092, {0x06, 0x00, 0x00, 0x00, 0x00}, 0x05},
+	{PRO_DMOD, 0x0099, {0x01}, 0x01},
+	{PRO_DMOD, 0x009b, {0x3c, 0x28}, 0x02},
+	{PRO_DMOD, 0x009f, {0xe1, 0xcf}, 0x02},
+	{PRO_DMOD, 0x00a3, {0x01, 0x5a, 0x01, 0x01}, 0x04},
+	{PRO_DMOD, 0x00a9, {0x00, 0x01}, 0x02},
+	{PRO_DMOD, 0x00b0, {0x01}, 0x01},
+	{PRO_DMOD, 0x00b3, {0x02, 0x3a}, 0x02},
+	{PRO_DMOD, 0x00b6, {0x14}, 0x01},
+	{PRO_DMOD, 0x00c0, {0x11, 0x00, 0x05, 0x01, 0x00}, 0x05},
+	{PRO_DMOD, 0x00c6, {0x19, 0x00}, 0x02},
+	{PRO_DMOD, 0x00cb, {0x32, 0x2c, 0x4f, 0x30}, 0x04},
+	{PRO_DMOD, 0x00f3, {0x05, 0x8c, 0x8c}, 0x03},
+	{PRO_DMOD, 0x00f8, {0x03, 0x06, 0x06}, 0x03},
+	{PRO_DMOD, 0x00fc, {	0x02, 0x03, 0x02, 0x09, 0x50, 0x6e, 0x8c,
+				0x02, 0x02, 0xc2, 0x00}, 0x0b},
+	{PRO_DMOD, 0x0109, {0x02}, 0x01},
+	{PRO_DMOD, 0x0115, {0x0a, 0x03}, 0x02},
+	{PRO_DMOD, 0x011a, {0xb8}, 0x01},
+	{PRO_DMOD, 0x0124, {0xa8}, 0x01},
+	{PRO_DMOD, 0x0127, {0x00}, 0x01},
+	{PRO_DMOD, 0x012a, {0x53, 0x51, 0x4e, 0x43}, 0x04},
+	{PRO_DMOD, 0x0137, {0x00}, 0x01},
+	{PRO_DMOD, 0x013b, {0x05}, 0x01},
+	{PRO_DMOD, 0x013f, {0x5b}, 0x01},
+	{PRO_DMOD, 0x0141, {	0x59, 0xf9, 0x59, 0x19, 0x8c, 0x8c, 0x8c,
+				0x7b, 0x8c, 0x50, 0x70, 0x8c, 0x96, 0xd0,
+				0x33}, 0x0f},
+	{PRO_DMOD, 0x0151, {0x28}, 0x01},
+	{PRO_DMOD, 0x0153, {0xb2}, 0x01},
+	{PRO_DMOD, 0x0178, {0x09}, 0x01},
+	{PRO_DMOD, 0x0181, {0x9c, 0x6e}, 0x02},
+	{PRO_DMOD, 0x0185, {0x24}, 0x01},
+	{PRO_DMOD, 0x0187, {0x00, 0x00, 0xb8, 0x02, 0x80}, 0x05},
+	{PRO_DMOD, 0xed02, {0xff}, 0x01},
+	{PRO_DMOD, 0xee42, {0xff}, 0x01},
+	{PRO_DMOD, 0xee82, {0xff}, 0x01},
+	{PRO_DMOD, 0xf000, {0x0f}, 0x01},
+	{PRO_DMOD, 0xf01f, {0x8c, 0x00}, 0x02},
+	{PRO_DMOD, 0xf029, {0x8c, 0x00, 0x00}, 0x03},
+	{PRO_DMOD, 0xf064, {0x03, 0xf9, 0x03, 0x01}, 0x04},
+	{PRO_DMOD, 0xf06f, {0xe0, 0x03}, 0x02},
+	{PRO_DMOD, 0xf072, {0x0f, 0x03}, 0x02},
+	{PRO_DMOD, 0xf077, {0x01, 0x00}, 0x02},
+	{PRO_DMOD, 0xf087, {0x00}, 0x01},
+	{PRO_DMOD, 0xf09b, {0x3f, 0x00, 0x20, 0x00, 0x0c, 0x00}, 0x06},
+	{PRO_DMOD, 0xf130, {0x04}, 0x01},
+	{PRO_DMOD, 0xf132, {0x04}, 0x01},
+	{PRO_DMOD, 0xf144, {0x1a}, 0x01},
+	{PRO_DMOD, 0xf146, {0x00}, 0x01},
+	{PRO_DMOD, 0xf14a, {0x01}, 0x01},
+	{PRO_DMOD, 0xf14c, {0x00, 0x00}, 0x02},
+	{PRO_DMOD, 0xf14f, {0x04}, 0x01},
+	{PRO_DMOD, 0xf158, {0x7f}, 0x01},
+	{PRO_DMOD, 0xf15a, {0x00, 0x08}, 0x02},
+	{PRO_DMOD, 0xf15d, {0x03, 0x05}, 0x02},
+	{PRO_DMOD, 0xf163, {0x05}, 0x01},
+	{PRO_DMOD, 0xf166, {0x01, 0x40, 0x0f}, 0x03},
+	{PRO_DMOD, 0xf17a, {0x00, 0x00}, 0x02},
+	{PRO_DMOD, 0xf183, {0x01}, 0x01},
+	{PRO_DMOD, 0xf19d, {0x40}, 0x01},
+	{PRO_DMOD, 0xf1bc, {0x36, 0x00}, 0x02},
+	{PRO_DMOD, 0xf1cb, {0xa0, 0x01}, 0x02},
+	{PRO_DMOD, 0xf204, {0x10}, 0x01},
+	{PRO_DMOD, 0xf214, {0x00}, 0x01},
+	{PRO_DMOD, 0xf24c, {0x88, 0x95, 0x9a, 0x90}, 0x04},
+	{PRO_DMOD, 0xf25a, {0x07, 0xe8, 0x03, 0xb0, 0x04}, 0x05},
+	{PRO_DMOD, 0xf270, {0x01, 0x02, 0x01, 0x02}, 0x04},
+	{PRO_DMOD, 0xf40e, {0x0a, 0x40, 0x08}, 0x03},
+	{PRO_DMOD, 0xf55f, {0x0a}, 0x01},
+	{PRO_DMOD, 0xf561, {0x15, 0x20}, 0x02},
+	{PRO_DMOD, 0xf5e3, {0x09, 0x01, 0x01}, 0x03},
+	{PRO_DMOD, 0xf600, {	0x05, 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x17,
+				0x1f}, 0x08},
+	{PRO_DMOD, 0xf60e, {0x00, 0x04, 0x32, 0x10}, 0x04},
+	{PRO_DMOD, 0xf707, {0xfc, 0x00, 0x37, 0x00}, 0x04},
+	{PRO_DMOD, 0xf78b, {0x01}, 0x01},
+	{PRO_DMOD, 0xf80f, {0x40, 0x54, 0x5a}, 0x03},
+	{PRO_DMOD, 0xf905, {0x01}, 0x01},
+	{PRO_DMOD, 0xfb06, {0x03}, 0x01},
+	{PRO_DMOD, 0xfd8b, {0x00}, 0x01},
+	{0xff, 0x0000, {0x00}, 0x00} /* Terminating Entry */
+};
+
+/* Tuner setting scripts (still keeping it9137) */
 static struct it913xset it9137_tuner_off[] = {
 	{PRO_DMOD, 0xfba8, {0x01}, 0x01}, /* Tuner Clock Off  */
 	{PRO_DMOD, 0xec40, {0x00}, 0x01}, /* Power Down Tuner */
 	{PRO_DMOD, 0xec02, {0x3f, 0x1f, 0x3f, 0x3f}, 0x04},
+	{PRO_DMOD, 0xec06, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00}, 0x0c},
+	{PRO_DMOD, 0xec12, {0x00, 0x00, 0x00, 0x00}, 0x04},
+	{PRO_DMOD, 0xec17, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00}, 0x09},
+	{PRO_DMOD, 0xec22, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00}, 0x0a},
+	{PRO_DMOD, 0xec20, {0x00}, 0x01},
 	{PRO_DMOD, 0xec3f, {0x01}, 0x01},
 	{0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */
 };
 
+static struct it913xset set_it9135_template[] = {
+	{PRO_DMOD, 0xee06, {0x00}, 0x01},
+	{PRO_DMOD, 0xec56, {0x00}, 0x01},
+	{PRO_DMOD, 0xec4c, {0x00}, 0x01},
+	{PRO_DMOD, 0xec4d, {0x00}, 0x01},
+	{PRO_DMOD, 0xec4e, {0x00}, 0x01},
+	{PRO_DMOD, 0x011e, {0x00}, 0x01}, /* Older Devices */
+	{PRO_DMOD, 0x011f, {0x00}, 0x01},
+	{0xff, 0x0000, {0x00}, 0x00}, /* Terminating Entry */
+};
+
 static struct it913xset set_it9137_template[] = {
 	{PRO_DMOD, 0xee06, {0x00}, 0x01},
 	{PRO_DMOD, 0xec56, {0x00}, 0x01},
diff --git a/drivers/media/dvb/frontends/it913x-fe.c b/drivers/media/dvb/frontends/it913x-fe.c
index d4bd24e..8088e62 100644
--- a/drivers/media/dvb/frontends/it913x-fe.c
+++ b/drivers/media/dvb/frontends/it913x-fe.c
@@ -46,13 +46,17 @@
 	  dprintk(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \
 		*p, *(p+1), *(p+2), *(p+3), *(p+4), \
 			*(p+5), *(p+6), *(p+7));
+#define info(format, arg...) \
+	printk(KERN_INFO "it913x-fe: " format "\n" , ## arg)
 
 struct it913x_fe_state {
 	struct dvb_frontend frontend;
 	struct i2c_adapter *i2c_adap;
+	struct ite_config *config;
 	u8 i2c_addr;
 	u32 frequency;
-	u8 adf;
+	fe_modulation_t constellation;
+	fe_transmit_mode_t transmission_mode;
 	u32 crystalFrequency;
 	u32 adcFrequency;
 	u8 tuner_type;
@@ -211,13 +215,17 @@
 	state->tun_fn_min /= (state->tun_fdiv * nv_val);
 	deb_info("Tuner fn_min %d", state->tun_fn_min);
 
-	for (i = 0; i < 50; i++) {
-		reg = it913x_read_reg_u8(state, 0xec82);
-		if (reg > 0)
-			break;
-		if (reg < 0)
-			return -ENODEV;
-		udelay(2000);
+	if (state->config->chip_ver > 1)
+		msleep(50);
+	else {
+		for (i = 0; i < 50; i++) {
+			reg = it913x_read_reg_u8(state, 0xec82);
+			if (reg > 0)
+				break;
+			if (reg < 0)
+				return -ENODEV;
+			udelay(2000);
+		}
 	}
 
 	return it913x_write_reg(state, PRO_DMOD, 0xed81, val);
@@ -237,6 +245,11 @@
 	u8 lna_band;
 	u8 bw;
 
+	if (state->config->firmware_ver == 1)
+		set_tuner = set_it9135_template;
+	else
+		set_tuner = set_it9137_template;
+
 	deb_info("Tuner Frequency %d Bandwidth %d", frequency, bandwidth);
 
 	if (frequency >= 51000 && frequency <= 440000) {
@@ -492,14 +505,50 @@
 	return 0;
 }
 
-static int it913x_fe_read_snr(struct dvb_frontend *fe, u16* snr)
+static int it913x_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
 {
 	struct it913x_fe_state *state = fe->demodulator_priv;
-	int ret = it913x_read_reg_u8(state, SIGNAL_QUALITY);
-	ret = (ret * 0xff) / 0x64;
-	ret |= (ret << 0x8);
-	*snr = ~ret;
-	return 0;
+	int ret;
+	u8 reg[3];
+	u32 snr_val, snr_min, snr_max;
+	u32 temp;
+
+	ret = it913x_read_reg(state, 0x2c, reg, sizeof(reg));
+
+	snr_val = (u32)(reg[2] << 16) | (reg[1] < 8) | reg[0];
+
+	ret |= it913x_read_reg(state, 0xf78b, reg, 1);
+	if (reg[0])
+		snr_val /= reg[0];
+
+	if (state->transmission_mode == TRANSMISSION_MODE_2K)
+		snr_val *= 4;
+	else if (state->transmission_mode == TRANSMISSION_MODE_4K)
+		snr_val *= 2;
+
+	if (state->constellation == QPSK) {
+		snr_min = 0xb4711;
+		snr_max = 0x191451;
+	} else if (state->constellation == QAM_16) {
+		snr_min = 0x4f0d5;
+		snr_max = 0xc7925;
+	} else if (state->constellation == QAM_64) {
+		snr_min = 0x256d0;
+		snr_max = 0x626be;
+	} else
+		return -EINVAL;
+
+	if (snr_val < snr_min)
+		*snr = 0;
+	else if (snr_val < snr_max) {
+		temp = (snr_val - snr_min) >> 5;
+		temp *= 0xffff;
+		temp /= (snr_max - snr_min) >> 5;
+		*snr = (u16)temp;
+	} else
+		*snr = 0xffff;
+
+	return (ret < 0) ? -ENODEV : 0;
 }
 
 static int it913x_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
@@ -526,9 +575,13 @@
 	if (reg[3] < 3)
 		p->u.ofdm.constellation = fe_con[reg[3]];
 
+	state->constellation = p->u.ofdm.constellation;
+
 	if (reg[0] < 3)
 		p->u.ofdm.transmission_mode = fe_mode[reg[0]];
 
+	state->transmission_mode = p->u.ofdm.transmission_mode;
+
 	if (reg[1] < 4)
 		p->u.ofdm.guard_interval = fe_gi[reg[1]];
 
@@ -578,7 +631,12 @@
 
 	deb_info("Frontend Set Tuner Type %02x", state->tuner_type);
 	switch (state->tuner_type) {
-	case IT9137: /* Tuner type 0x38 */
+	case IT9135_38:
+	case IT9135_51:
+	case IT9135_52:
+	case IT9135_60:
+	case IT9135_61:
+	case IT9135_62:
 		ret = it9137_set_tuner(state,
 			p->u.ofdm.bandwidth, p->frequency);
 		break;
@@ -678,16 +736,19 @@
 
 static int it913x_fe_start(struct it913x_fe_state *state)
 {
-	struct it913xset *set_fe;
+	struct it913xset *set_lna;
 	struct it913xset *set_mode;
 	int ret;
-	u8 adf = (state->adf & 0xf);
+	u8 adf = (state->config->adf & 0xf);
 	u32 adc, xtal;
 	u8 b[4];
 
-	ret = it913x_init_tuner(state);
+	if (state->config->chip_ver == 1)
+		ret = it913x_init_tuner(state);
 
-	if (adf < 12) {
+	info("ADF table value	:%02x", adf);
+
+	if (adf < 10) {
 		state->crystalFrequency = fe_clockTable[adf].xtal ;
 		state->table = fe_clockTable[adf].table;
 		state->adcFrequency = state->table->adcFrequency;
@@ -698,9 +759,6 @@
 	} else
 		return -EINVAL;
 
-	deb_info("Xtal Freq :%d Adc Freq :%d Adc %08x Xtal %08x",
-		state->crystalFrequency, state->adcFrequency, adc, xtal);
-
 	/* Set LED indicator on GPIOH3 */
 	ret = it913x_write_reg(state, PRO_LINK, GPIOH3_EN, 0x1);
 	ret |= it913x_write_reg(state, PRO_LINK, GPIOH3_ON, 0x1);
@@ -721,22 +779,71 @@
 	b[2] = (adc >> 16) & 0xff;
 	ret |= it913x_write(state, PRO_DMOD, ADC_FREQ, b, 3);
 
-	switch (state->tuner_type) {
-	case IT9137: /* Tuner type 0x38 */
-		set_fe = it9137_set;
-		break;
-	default:
-		return -EINVAL;
-	}
+	if (state->config->adc_x2)
+		ret |= it913x_write_reg(state, PRO_DMOD, ADC_X_2, 0x01);
+	b[0] = 0;
+	b[1] = 0;
+	b[2] = 0;
+	ret |= it913x_write(state, PRO_DMOD, 0x0029, b, 3);
 
-	/* set the demod */
-	ret = it913x_fe_script_loader(state, set_fe);
+	info("Crystal Frequency :%d Adc Frequency :%d ADC X2: %02x",
+		state->crystalFrequency, state->adcFrequency,
+			state->config->adc_x2);
+	deb_info("Xtal value :%04x Adc value :%04x", xtal, adc);
+
+	if (ret < 0)
+		return -ENODEV;
+
+	/* v1 or v2 tuner script */
+	if (state->config->chip_ver > 1)
+		ret = it913x_fe_script_loader(state, it9135_v2);
+	else
+		ret = it913x_fe_script_loader(state, it9135_v1);
+	if (ret < 0)
+		return ret;
+
+	/* LNA Scripts */
+	switch (state->tuner_type) {
+	case IT9135_51:
+		set_lna = it9135_51;
+		break;
+	case IT9135_52:
+		set_lna = it9135_52;
+		break;
+	case IT9135_60:
+		set_lna = it9135_60;
+		break;
+	case IT9135_61:
+		set_lna = it9135_61;
+		break;
+	case IT9135_62:
+		set_lna = it9135_62;
+		break;
+	case IT9135_38:
+	default:
+		set_lna = it9135_38;
+	}
+	info("Tuner LNA type :%02x", state->tuner_type);
+
+	ret = it913x_fe_script_loader(state, set_lna);
+	if (ret < 0)
+		return ret;
+
+	if (state->config->chip_ver == 2) {
+		ret = it913x_write_reg(state, PRO_DMOD, TRIGGER_OFSM, 0x1);
+		ret |= it913x_write_reg(state, PRO_LINK, PADODPU, 0x0);
+		ret |= it913x_write_reg(state, PRO_LINK, AGC_O_D, 0x0);
+		ret |= it913x_init_tuner(state);
+	}
+	if (ret < 0)
+		return -ENODEV;
+
 	/* Always solo frontend */
 	set_mode = set_solo_fe;
 	ret |= it913x_fe_script_loader(state, set_mode);
 
 	ret |= it913x_fe_suspend(state);
-	return 0;
+	return (ret < 0) ? -ENODEV : 0;
 }
 
 static int it913x_fe_init(struct dvb_frontend *fe)
@@ -746,17 +853,11 @@
 	/* Power Up Tuner - common all versions */
 	ret = it913x_write_reg(state, PRO_DMOD, 0xec40, 0x1);
 
-	ret |= it913x_write_reg(state, PRO_DMOD, AFE_MEM0, 0x0);
-
 	ret |= it913x_fe_script_loader(state, init_1);
 
-	switch (state->tuner_type) {
-	case IT9137:
-		ret |= it913x_write_reg(state, PRO_DMOD, 0xfba8, 0x0);
-		break;
-	default:
-		return -EINVAL;
-	}
+	ret |= it913x_write_reg(state, PRO_DMOD, AFE_MEM0, 0x0);
+
+	ret |= it913x_write_reg(state, PRO_DMOD, 0xfba8, 0x0);
 
 	return (ret < 0) ? -ENODEV : 0;
 }
@@ -770,19 +871,34 @@
 static struct dvb_frontend_ops it913x_fe_ofdm_ops;
 
 struct dvb_frontend *it913x_fe_attach(struct i2c_adapter *i2c_adap,
-		u8 i2c_addr, u8 adf, u8 type)
+		u8 i2c_addr, struct ite_config *config)
 {
 	struct it913x_fe_state *state = NULL;
 	int ret;
+
 	/* allocate memory for the internal state */
 	state = kzalloc(sizeof(struct it913x_fe_state), GFP_KERNEL);
 	if (state == NULL)
+		return NULL;
+	if (config == NULL)
 		goto error;
 
 	state->i2c_adap = i2c_adap;
 	state->i2c_addr = i2c_addr;
-	state->adf = adf;
-	state->tuner_type = type;
+	state->config = config;
+
+	switch (state->config->tuner_id_0) {
+	case IT9135_51:
+	case IT9135_52:
+	case IT9135_60:
+	case IT9135_61:
+	case IT9135_62:
+		state->tuner_type = state->config->tuner_id_0;
+		break;
+	default:
+	case IT9135_38:
+		state->tuner_type = IT9135_38;
+	}
 
 	ret = it913x_fe_start(state);
 	if (ret < 0)
@@ -835,5 +951,5 @@
 
 MODULE_DESCRIPTION("it913x Frontend and it9137 tuner");
 MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
-MODULE_VERSION("1.07");
+MODULE_VERSION("1.12");
 MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/it913x-fe.h b/drivers/media/dvb/frontends/it913x-fe.h
index 9d97f32..4143ef9 100644
--- a/drivers/media/dvb/frontends/it913x-fe.h
+++ b/drivers/media/dvb/frontends/it913x-fe.h
@@ -23,13 +23,27 @@
 
 #include <linux/dvb/frontend.h>
 #include "dvb_frontend.h"
+
+struct ite_config {
+	u8 chip_ver;
+	u16 chip_type;
+	u32 firmware;
+	u8 firmware_ver;
+	u8 adc_x2;
+	u8 tuner_id_0;
+	u8 tuner_id_1;
+	u8 dual_mode;
+	u8 adf;
+};
+
 #if defined(CONFIG_DVB_IT913X_FE) || (defined(CONFIG_DVB_IT913X_FE_MODULE) && \
 defined(MODULE))
 extern struct dvb_frontend *it913x_fe_attach(struct i2c_adapter *i2c_adap,
-			u8 i2c_addr, u8 adf, u8 type);
+			u8 i2c_addr, struct ite_config *config);
 #else
 static inline struct dvb_frontend *it913x_fe_attach(
-		struct i2c_adapter *i2c_adap,	u8 i2c_addr, u8 adf, u8 type)
+		struct i2c_adapter *i2c_adap,
+			u8 i2c_addr, struct ite_config *config)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
@@ -144,8 +158,14 @@
 #define EST_SIGNAL_LEVEL	0x004a
 #define FREE_BAND		0x004b
 #define SUSPEND_FLAG		0x004c
-/* Build in tuners */
+/* Build in tuner types */
 #define IT9137 0x38
+#define IT9135_38 0x38
+#define IT9135_51 0x50
+#define IT9135_52 0x52
+#define IT9135_60 0x60
+#define IT9135_61 0x61
+#define IT9135_62 0x62
 
 enum {
 	CMD_DEMOD_READ = 0,
@@ -193,4 +213,11 @@
 	WRITE_CMD,
 };
 
+enum {
+	IT9135_AUTO = 0,
+	IT9137_FW,
+	IT9135_V1_FW,
+	IT9135_V2_FW,
+};
+
 #endif /* IT913X_FE_H */
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c
index 0e2f61a..0d6d5e3 100644
--- a/drivers/media/dvb/frontends/s5h1409.c
+++ b/drivers/media/dvb/frontends/s5h1409.c
@@ -879,7 +879,36 @@
 static int s5h1409_read_signal_strength(struct dvb_frontend *fe,
 					u16 *signal_strength)
 {
-	return s5h1409_read_snr(fe, signal_strength);
+	/* borrowed from lgdt330x.c
+	 *
+	 * Calculate strength from SNR up to 35dB
+	 * Even though the SNR can go higher than 35dB,
+	 * there is some comfort factor in having a range of
+	 * strong signals that can show at 100%
+	 */
+	u16 snr;
+	u32 tmp;
+	int ret = s5h1409_read_snr(fe, &snr);
+
+	*signal_strength = 0;
+
+	if (0 == ret) {
+		/* The following calculation method was chosen
+		 * purely for the sake of code re-use from the
+		 * other demod drivers that use this method */
+
+		/* Convert from SNR in dB * 10 to 8.24 fixed-point */
+		tmp = (snr * ((1 << 24) / 10));
+
+		/* Convert from 8.24 fixed-point to
+		 * scale the range 0 - 35*2^24 into 0 - 65535*/
+		if (tmp >= 8960 * 0x10000)
+			*signal_strength = 0xffff;
+		else
+			*signal_strength = tmp / 8960;
+	}
+
+	return ret;
 }
 
 static int s5h1409_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c
index d8adf1e..5fca113 100644
--- a/drivers/media/dvb/frontends/s5h1411.c
+++ b/drivers/media/dvb/frontends/s5h1411.c
@@ -794,7 +794,36 @@
 static int s5h1411_read_signal_strength(struct dvb_frontend *fe,
 	u16 *signal_strength)
 {
-	return s5h1411_read_snr(fe, signal_strength);
+	/* borrowed from lgdt330x.c
+	 *
+	 * Calculate strength from SNR up to 35dB
+	 * Even though the SNR can go higher than 35dB,
+	 * there is some comfort factor in having a range of
+	 * strong signals that can show at 100%
+	 */
+	u16 snr;
+	u32 tmp;
+	int ret = s5h1411_read_snr(fe, &snr);
+
+	*signal_strength = 0;
+
+	if (0 == ret) {
+		/* The following calculation method was chosen
+		 * purely for the sake of code re-use from the
+		 * other demod drivers that use this method */
+
+		/* Convert from SNR in dB * 10 to 8.24 fixed-point */
+		tmp = (snr * ((1 << 24) / 10));
+
+		/* Convert from 8.24 fixed-point to
+		 * scale the range 0 - 35*2^24 into 0 - 65535*/
+		if (tmp >= 8960 * 0x10000)
+			*signal_strength = 0xffff;
+		else
+			*signal_strength = tmp / 8960;
+	}
+
+	return ret;
 }
 
 static int s5h1411_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c
index 8408ef8..9c93d9f 100644
--- a/drivers/media/dvb/frontends/stb0899_drv.c
+++ b/drivers/media/dvb/frontends/stb0899_drv.c
@@ -1605,6 +1605,21 @@
 	return DVBFE_ALGO_CUSTOM;
 }
 
+static int stb0899_get_property(struct dvb_frontend *fe, struct dtv_property *p)
+{
+	switch (p->cmd) {
+	case DTV_ENUM_DELSYS:
+		p->u.buffer.data[0] = SYS_DSS;
+		p->u.buffer.data[1] = SYS_DVBS;
+		p->u.buffer.data[2] = SYS_DVBS2;
+		p->u.buffer.len = 3;
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
 static struct dvb_frontend_ops stb0899_ops = {
 
 	.info = {
@@ -1647,6 +1662,8 @@
 	.diseqc_send_master_cmd		= stb0899_send_diseqc_msg,
 	.diseqc_recv_slave_reply	= stb0899_recv_slave_reply,
 	.diseqc_send_burst		= stb0899_send_diseqc_burst,
+
+	.get_property			= stb0899_get_property,
 };
 
 struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_adapter *i2c)
diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c
index 0ca316d..2b8d78c 100644
--- a/drivers/media/dvb/frontends/stv0900_core.c
+++ b/drivers/media/dvb/frontends/stv0900_core.c
@@ -985,7 +985,16 @@
 				struct dtv_property *tvp)
 {
 	dprintk("%s(..)\n", __func__);
-
+	switch (tvp->cmd) {
+	case DTV_ENUM_DELSYS:
+		tvp->u.buffer.data[0] = SYS_DSS;
+		tvp->u.buffer.data[1] = SYS_DVBS;
+		tvp->u.buffer.data[2] = SYS_DVBS2;
+		tvp->u.buffer.len = 3;
+		break;
+	default:
+		break;
+	}
 	return 0;
 }
 
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c
index ebda419..8a2637c 100644
--- a/drivers/media/dvb/frontends/stv090x.c
+++ b/drivers/media/dvb/frontends/stv090x.c
@@ -4711,6 +4711,21 @@
 }
 EXPORT_SYMBOL(stv090x_set_gpio);
 
+static int stv090x_get_property(struct dvb_frontend *fe, struct dtv_property *p)
+{
+	switch (p->cmd) {
+	case DTV_ENUM_DELSYS:
+		p->u.buffer.data[0] = SYS_DSS;
+		p->u.buffer.data[1] = SYS_DVBS;
+		p->u.buffer.data[2] = SYS_DVBS2;
+		p->u.buffer.len = 3;
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
 static struct dvb_frontend_ops stv090x_ops = {
 
 	.info = {
@@ -4743,7 +4758,9 @@
 	.read_status			= stv090x_read_status,
 	.read_ber			= stv090x_read_per,
 	.read_signal_strength		= stv090x_read_signal_strength,
-	.read_snr			= stv090x_read_cnr
+	.read_snr			= stv090x_read_cnr,
+
+	.get_property			= stv090x_get_property,
 };
 
 
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
index 6ca533e..2518c5a 100644
--- a/drivers/media/dvb/frontends/tda10021.c
+++ b/drivers/media/dvb/frontends/tda10021.c
@@ -224,29 +224,60 @@
 	return 0;
 }
 
+struct qam_params {
+	u8 conf, agcref, lthr, mseth, aref;
+};
+
 static int tda10021_set_parameters (struct dvb_frontend *fe,
 			    struct dvb_frontend_parameters *p)
 {
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	u32 delsys  = c->delivery_system;
+	unsigned qam = c->modulation;
+	bool is_annex_c;
+	u32 reg0x3d;
 	struct tda10021_state* state = fe->demodulator_priv;
+	static const struct qam_params qam_params[] = {
+		/* Modulation  Conf  AGCref  LTHR  MSETH  AREF */
+		[QPSK]	   = { 0x14, 0x78,   0x78, 0x8c,  0x96 },
+		[QAM_16]   = { 0x00, 0x8c,   0x87, 0xa2,  0x91 },
+		[QAM_32]   = { 0x04, 0x8c,   0x64, 0x74,  0x96 },
+		[QAM_64]   = { 0x08, 0x6a,   0x46, 0x43,  0x6a },
+		[QAM_128]  = { 0x0c, 0x78,   0x36, 0x34,  0x7e },
+		[QAM_256]  = { 0x10, 0x5c,   0x26, 0x23,  0x6b },
+	};
 
-	//table for QAM4-QAM256 ready  QAM4  QAM16 QAM32 QAM64 QAM128 QAM256
-	//CONF
-	static const u8 reg0x00 [] = { 0x14, 0x00, 0x04, 0x08, 0x0c,  0x10 };
-	//AGCREF value
-	static const u8 reg0x01 [] = { 0x78, 0x8c, 0x8c, 0x6a, 0x78,  0x5c };
-	//LTHR value
-	static const u8 reg0x05 [] = { 0x78, 0x87, 0x64, 0x46, 0x36,  0x26 };
-	//MSETH
-	static const u8 reg0x08 [] = { 0x8c, 0xa2, 0x74, 0x43, 0x34,  0x23 };
-	//AREF
-	static const u8 reg0x09 [] = { 0x96, 0x91, 0x96, 0x6a, 0x7e,  0x6b };
-
-	int qam = p->u.qam.modulation;
-
-	if (qam < 0 || qam > 5)
+	switch (delsys) {
+	case SYS_DVBC_ANNEX_A:
+		is_annex_c = false;
+		break;
+	case SYS_DVBC_ANNEX_C:
+		is_annex_c = true;
+		break;
+	default:
 		return -EINVAL;
+	}
 
-	if (p->inversion != INVERSION_ON && p->inversion != INVERSION_OFF)
+	/*
+	 * gcc optimizes the code bellow the same way as it would code:
+	 *           "if (qam > 5) return -EINVAL;"
+	 * Yet, the code is clearer, as it shows what QAM standards are
+	 * supported by the driver, and avoids the usage of magic numbers on
+	 * it.
+	 */
+	switch (qam) {
+	case QPSK:
+	case QAM_16:
+	case QAM_32:
+	case QAM_64:
+	case QAM_128:
+	case QAM_256:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (c->inversion != INVERSION_ON && c->inversion != INVERSION_OFF)
 		return -EINVAL;
 
 	//printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate);
@@ -256,15 +287,24 @@
 		if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
 	}
 
-	tda10021_set_symbolrate (state, p->u.qam.symbol_rate);
-	_tda10021_writereg (state, 0x34, state->pwm);
+	tda10021_set_symbolrate(state, c->symbol_rate);
+	_tda10021_writereg(state, 0x34, state->pwm);
 
-	_tda10021_writereg (state, 0x01, reg0x01[qam]);
-	_tda10021_writereg (state, 0x05, reg0x05[qam]);
-	_tda10021_writereg (state, 0x08, reg0x08[qam]);
-	_tda10021_writereg (state, 0x09, reg0x09[qam]);
+	_tda10021_writereg(state, 0x01, qam_params[qam].agcref);
+	_tda10021_writereg(state, 0x05, qam_params[qam].lthr);
+	_tda10021_writereg(state, 0x08, qam_params[qam].mseth);
+	_tda10021_writereg(state, 0x09, qam_params[qam].aref);
 
-	tda10021_setup_reg0 (state, reg0x00[qam], p->inversion);
+	/*
+	 * Bit 0 == 0 means roll-off = 0.15 (Annex A)
+	 *	 == 1 means roll-off = 0.13 (Annex C)
+	 */
+	reg0x3d = tda10021_readreg (state, 0x3d);
+	if (is_annex_c)
+		_tda10021_writereg (state, 0x3d, 0x01 | reg0x3d);
+	else
+		_tda10021_writereg (state, 0x3d, 0xfe & reg0x3d);
+	tda10021_setup_reg0(state, qam_params[qam].conf, c->inversion);
 
 	return 0;
 }
@@ -443,6 +483,21 @@
 	return NULL;
 }
 
+static int tda10021_get_property(struct dvb_frontend *fe,
+				 struct dtv_property *p)
+{
+	switch (p->cmd) {
+	case DTV_ENUM_DELSYS:
+		p->u.buffer.data[0] = SYS_DVBC_ANNEX_A;
+		p->u.buffer.data[1] = SYS_DVBC_ANNEX_C;
+		p->u.buffer.len = 2;
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
 static struct dvb_frontend_ops tda10021_ops = {
 
 	.info = {
@@ -471,6 +526,7 @@
 
 	.set_frontend = tda10021_set_parameters,
 	.get_frontend = tda10021_get_frontend,
+	.get_property = tda10021_get_property,
 
 	.read_status = tda10021_read_status,
 	.read_ber = tda10021_read_ber,
diff --git a/drivers/media/dvb/frontends/tda10023.c b/drivers/media/dvb/frontends/tda10023.c
index a3c34ee..af7f1b8 100644
--- a/drivers/media/dvb/frontends/tda10023.c
+++ b/drivers/media/dvb/frontends/tda10023.c
@@ -298,43 +298,97 @@
 	return 0;
 }
 
+struct qam_params {
+	u8 qam, lockthr, mseth, aref, agcrefnyq, eragnyq_thd;
+};
+
 static int tda10023_set_parameters (struct dvb_frontend *fe,
 			    struct dvb_frontend_parameters *p)
 {
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	u32 delsys  = c->delivery_system;
+	unsigned qam = c->modulation;
+	bool is_annex_c;
 	struct tda10023_state* state = fe->demodulator_priv;
-
-	static int qamvals[6][6] = {
-		//  QAM   LOCKTHR  MSETH   AREF AGCREFNYQ  ERAGCNYQ_THD
-		{ (5<<2),  0x78,    0x8c,   0x96,   0x78,   0x4c  },  // 4 QAM
-		{ (0<<2),  0x87,    0xa2,   0x91,   0x8c,   0x57  },  // 16 QAM
-		{ (1<<2),  0x64,    0x74,   0x96,   0x8c,   0x57  },  // 32 QAM
-		{ (2<<2),  0x46,    0x43,   0x6a,   0x6a,   0x44  },  // 64 QAM
-		{ (3<<2),  0x36,    0x34,   0x7e,   0x78,   0x4c  },  // 128 QAM
-		{ (4<<2),  0x26,    0x23,   0x6c,   0x5c,   0x3c  },  // 256 QAM
+	static const struct qam_params qam_params[] = {
+		/* Modulation  QAM    LOCKTHR   MSETH   AREF AGCREFNYQ ERAGCNYQ_THD */
+		[QPSK]    = { (5<<2),  0x78,    0x8c,   0x96,   0x78,   0x4c  },
+		[QAM_16]  = { (0<<2),  0x87,    0xa2,   0x91,   0x8c,   0x57  },
+		[QAM_32]  = { (1<<2),  0x64,    0x74,   0x96,   0x8c,   0x57  },
+		[QAM_64]  = { (2<<2),  0x46,    0x43,   0x6a,   0x6a,   0x44  },
+		[QAM_128] = { (3<<2),  0x36,    0x34,   0x7e,   0x78,   0x4c  },
+		[QAM_256] = { (4<<2),  0x26,    0x23,   0x6c,   0x5c,   0x3c  },
 	};
 
-	int qam = p->u.qam.modulation;
-
-	if (qam < 0 || qam > 5)
+	switch (delsys) {
+	case SYS_DVBC_ANNEX_A:
+		is_annex_c = false;
+		break;
+	case SYS_DVBC_ANNEX_C:
+		is_annex_c = true;
+		break;
+	default:
 		return -EINVAL;
+	}
+
+	/*
+	 * gcc optimizes the code bellow the same way as it would code:
+	 *		 "if (qam > 5) return -EINVAL;"
+	 * Yet, the code is clearer, as it shows what QAM standards are
+	 * supported by the driver, and avoids the usage of magic numbers on
+	 * it.
+	 */
+	switch (qam) {
+	case QPSK:
+	case QAM_16:
+	case QAM_32:
+	case QAM_64:
+	case QAM_128:
+	case QAM_256:
+		break;
+	default:
+		return -EINVAL;
+	}
 
 	if (fe->ops.tuner_ops.set_params) {
 		fe->ops.tuner_ops.set_params(fe, p);
 		if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
 	}
 
-	tda10023_set_symbolrate (state, p->u.qam.symbol_rate);
-	tda10023_writereg (state, 0x05, qamvals[qam][1]);
-	tda10023_writereg (state, 0x08, qamvals[qam][2]);
-	tda10023_writereg (state, 0x09, qamvals[qam][3]);
-	tda10023_writereg (state, 0xb4, qamvals[qam][4]);
-	tda10023_writereg (state, 0xb6, qamvals[qam][5]);
+	tda10023_set_symbolrate(state, c->symbol_rate);
+	tda10023_writereg(state, 0x05, qam_params[qam].lockthr);
+	tda10023_writereg(state, 0x08, qam_params[qam].mseth);
+	tda10023_writereg(state, 0x09, qam_params[qam].aref);
+	tda10023_writereg(state, 0xb4, qam_params[qam].agcrefnyq);
+	tda10023_writereg(state, 0xb6, qam_params[qam].eragnyq_thd);
+#if 0
+	tda10023_writereg(state, 0x04, (c->inversion ? 0x12 : 0x32));
+	tda10023_writebit(state, 0x04, 0x60, (c->inversion ? 0 : 0x20));
+#endif
+	tda10023_writebit(state, 0x04, 0x40, 0x40);
 
-//	tda10023_writereg (state, 0x04, (p->inversion?0x12:0x32));
-//	tda10023_writebit (state, 0x04, 0x60, (p->inversion?0:0x20));
-	tda10023_writebit (state, 0x04, 0x40, 0x40);
-	tda10023_setup_reg0 (state, qamvals[qam][0]);
+	if (is_annex_c)
+		tda10023_writebit(state, 0x3d, 0xfc, 0x03);
+	else
+		tda10023_writebit(state, 0x3d, 0xfc, 0x02);
 
+	tda10023_setup_reg0(state, qam_params[qam].qam);
+
+	return 0;
+}
+
+static int tda10023_get_property(struct dvb_frontend *fe,
+				 struct dtv_property *p)
+{
+	switch (p->cmd) {
+	case DTV_ENUM_DELSYS:
+		p->u.buffer.data[0] = SYS_DVBC_ANNEX_A;
+		p->u.buffer.data[1] = SYS_DVBC_ANNEX_C;
+		p->u.buffer.len = 2;
+		break;
+	default:
+		break;
+	}
 	return 0;
 }
 
@@ -557,7 +611,7 @@
 
 	.set_frontend = tda10023_set_parameters,
 	.get_frontend = tda10023_get_frontend,
-
+	.get_property = tda10023_get_property,
 	.read_status = tda10023_read_status,
 	.read_ber = tda10023_read_ber,
 	.read_signal_strength = tda10023_read_signal_strength,
diff --git a/drivers/media/dvb/frontends/tda18271c2dd.c b/drivers/media/dvb/frontends/tda18271c2dd.c
index 1b1bf20..0f8e962 100644
--- a/drivers/media/dvb/frontends/tda18271c2dd.c
+++ b/drivers/media/dvb/frontends/tda18271c2dd.c
@@ -1123,20 +1123,6 @@
 	return 0;
 }
 
-/*
- * As defined on EN 300 429 Annex A and on ITU-T J.83 annex A, the DVB-C
- * roll-off factor is 0.15.
- * According with the specs, the amount of the needed bandwith is given by:
- *	Bw = Symbol_rate * (1 + 0.15)
- * As such, the maximum symbol rate supported by 6 MHz is
- *	max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds
- *NOTE: For ITU-T J.83 Annex C, the roll-off factor is 0.13. So:
- *	max_symbol_rate = 6 MHz / 1.13 = 5309735 Baud
- *	That means that an adjustment is needed for Japan,
- *	but, as currently DRX-K is hardcoded to Annex A, let's stick
- *	with 0.15 roll-off factor.
- */
-#define MAX_SYMBOL_RATE_6MHz	5217391
 
 static int set_params(struct dvb_frontend *fe,
 		      struct dvb_frontend_parameters *params)
@@ -1144,34 +1130,44 @@
 	struct tda_state *state = fe->tuner_priv;
 	int status = 0;
 	int Standard;
+	u32 bw = fe->dtv_property_cache.bandwidth_hz;
+	u32 delsys  = fe->dtv_property_cache.delivery_system;
 
-	state->m_Frequency = params->frequency;
+	state->m_Frequency = fe->dtv_property_cache.frequency;
 
-	if (fe->ops.info.type == FE_OFDM)
-		switch (params->u.ofdm.bandwidth) {
-		case BANDWIDTH_6_MHZ:
+	switch (delsys) {
+	case  SYS_DVBT:
+	case  SYS_DVBT2:
+		switch (bw) {
+		case 6000000:
 			Standard = HF_DVBT_6MHZ;
 			break;
-		case BANDWIDTH_7_MHZ:
+		case 7000000:
 			Standard = HF_DVBT_7MHZ;
 			break;
-		default:
-		case BANDWIDTH_8_MHZ:
+		case 8000000:
 			Standard = HF_DVBT_8MHZ;
 			break;
+		default:
+			return -EINVAL;
 		}
-	else if (fe->ops.info.type == FE_QAM) {
-		if (params->u.qam.symbol_rate <= MAX_SYMBOL_RATE_6MHz)
+	case SYS_DVBC_ANNEX_A:
+	case SYS_DVBC_ANNEX_C:
+		if (bw <= 6000000)
 			Standard = HF_DVBC_6MHZ;
+		else if (bw <= 7000000)
+			Standard = HF_DVBC_7MHZ;
 		else
 			Standard = HF_DVBC_8MHZ;
-	} else
+	default:
 		return -EINVAL;
+	}
 	do {
-		status = RFTrackingFiltersCorrection(state, params->frequency);
+		status = RFTrackingFiltersCorrection(state, state->m_Frequency);
 		if (status < 0)
 			break;
-		status = ChannelConfiguration(state, params->frequency, Standard);
+		status = ChannelConfiguration(state, state->m_Frequency,
+					      Standard);
 		if (status < 0)
 			break;
 
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 3d20719..abf6b55 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -991,7 +991,7 @@
 
 	if (feed->type == DMX_TYPE_TS) {
 		if ((feed->ts_type & TS_DECODER) &&
-		    (feed->pes_type < DMX_TS_PES_OTHER)) {
+		    (feed->pes_type <= DMX_TS_PES_PCR)) {
 			switch (demux->dmx.frontend->source) {
 			case DMX_MEMORY_FE:
 				if (feed->ts_type & TS_DECODER)
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index ca02e97..ab180f9 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -193,7 +193,6 @@
 	dev->input_phys = budget_ci->ir.phys;
 	dev->input_id.bustype = BUS_PCI;
 	dev->input_id.version = 1;
-	dev->scanmask = 0xff;
 	if (saa->pci->subsystem_vendor) {
 		dev->input_id.vendor = saa->pci->subsystem_vendor;
 		dev->input_id.product = saa->pci->subsystem_device;
@@ -234,6 +233,8 @@
 		dev->map_name = RC_MAP_BUDGET_CI_OLD;
 		break;
 	}
+	if (!budget_ci->ir.full_rc5)
+		dev->scanmask = 0xff;
 
 	error = rc_register_device(dev);
 	if (error) {
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 6edc9ba..6f9eb94 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -108,8 +108,7 @@
 	u_ent.group_id = ent->group_id;
 	u_ent.pads = ent->num_pads;
 	u_ent.links = ent->num_links - ent->num_backlinks;
-	u_ent.v4l.major = ent->v4l.major;
-	u_ent.v4l.minor = ent->v4l.minor;
+	memcpy(&u_ent.raw, &ent->info, sizeof(ent->info));
 	if (copy_to_user(uent, &u_ent, sizeof(u_ent)))
 		return -EFAULT;
 	return 0;
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index ccd5f0d..e954781 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -11,6 +11,162 @@
 
 if RADIO_ADAPTERS && VIDEO_V4L2
 
+config RADIO_SI470X
+	bool "Silicon Labs Si470x FM Radio Receiver support"
+	depends on VIDEO_V4L2
+
+source "drivers/media/radio/si470x/Kconfig"
+
+config USB_MR800
+	tristate "AverMedia MR 800 USB FM radio support"
+	depends on USB && VIDEO_V4L2
+	---help---
+	  Say Y here if you want to connect this type of radio to your
+	  computer's USB port. Note that the audio is not digital, and
+	  you must connect the line out connector to a sound card or a
+	  set of speakers.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called radio-mr800.
+
+config USB_DSBR
+	tristate "D-Link/GemTek USB FM radio support"
+	depends on USB && VIDEO_V4L2
+	---help---
+	  Say Y here if you want to connect this type of radio to your
+	  computer's USB port. Note that the audio is not digital, and
+	  you must connect the line out connector to a sound card or a
+	  set of speakers.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called dsbr100.
+
+config RADIO_MAXIRADIO
+	tristate "Guillemot MAXI Radio FM 2000 radio"
+	depends on VIDEO_V4L2 && PCI
+	---help---
+	  Choose Y here if you have this radio card.  This card may also be
+	  found as Gemtek PCI FM.
+
+	  In order to control your radio card, you will need to use programs
+	  that are compatible with the Video For Linux API.  Information on
+	  this API and pointers to "v4l" programs may be found at
+	  <file:Documentation/video4linux/API.html>.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called radio-maxiradio.
+
+
+config I2C_SI4713
+	tristate "I2C driver for Silicon Labs Si4713 device"
+	depends on I2C && VIDEO_V4L2
+	---help---
+	  Say Y here if you want support to Si4713 I2C device.
+	  This device driver supports only i2c bus.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called si4713.
+
+config RADIO_SI4713
+	tristate "Silicon Labs Si4713 FM Radio Transmitter support"
+	depends on I2C && VIDEO_V4L2
+	select I2C_SI4713
+	---help---
+	  Say Y here if you want support to Si4713 FM Radio Transmitter.
+	  This device can transmit audio through FM. It can transmit
+	  RDS and RBDS signals as well. This module is the v4l2 radio
+	  interface for the i2c driver of this device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called radio-si4713.
+
+config RADIO_TEA5764
+	tristate "TEA5764 I2C FM radio support"
+	depends on I2C && VIDEO_V4L2
+	---help---
+	  Say Y here if you want to use the TEA5764 FM chip found in
+	  EZX phones. This FM chip is present in EZX phones from Motorola,
+	  connected to internal pxa I2C bus.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called radio-tea5764.
+
+config RADIO_TEA5764_XTAL
+	bool "TEA5764 crystal reference"
+	depends on RADIO_TEA5764=y
+	default y
+	help
+	  Say Y here if TEA5764 have a 32768 Hz crystal in circuit, say N
+	  here if TEA5764 reference frequency is connected in FREQIN.
+
+config RADIO_SAA7706H
+	tristate "SAA7706H Car Radio DSP"
+	depends on I2C && VIDEO_V4L2
+	---help---
+	  Say Y here if you want to use the SAA7706H Car radio Digital
+	  Signal Processor, found for instance on the Russellville development
+	  board. On the russellville the device is connected to internal
+	  timberdale I2C bus.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called SAA7706H.
+
+config RADIO_TEF6862
+	tristate "TEF6862 Car Radio Enhanced Selectivity Tuner"
+	depends on I2C && VIDEO_V4L2
+	---help---
+	  Say Y here if you want to use the TEF6862 Car Radio Enhanced
+	  Selectivity Tuner, found for instance on the Russellville development
+	  board. On the russellville the device is connected to internal
+	  timberdale I2C bus.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called TEF6862.
+
+config RADIO_TIMBERDALE
+	tristate "Enable the Timberdale radio driver"
+	depends on MFD_TIMBERDALE && VIDEO_V4L2
+	depends on I2C	# for RADIO_SAA7706H
+	select RADIO_TEF6862
+	select RADIO_SAA7706H
+	---help---
+	  This is a kind of umbrella driver for the Radio Tuner and DSP
+	  found behind the Timberdale FPGA on the Russellville board.
+	  Enabling this driver will automatically select the DSP and tuner.
+
+config RADIO_WL1273
+	tristate "Texas Instruments WL1273 I2C FM Radio"
+	depends on I2C && VIDEO_V4L2
+	select MFD_CORE
+	select MFD_WL1273_CORE
+	select FW_LOADER
+	---help---
+	  Choose Y here if you have this FM radio chip.
+
+	  In order to control your radio card, you will need to use programs
+	  that are compatible with the Video For Linux 2 API.  Information on
+	  this API and pointers to "v4l2" programs may be found at
+	  <file:Documentation/video4linux/API.html>.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called radio-wl1273.
+
+# TI's ST based wl128x FM radio
+source "drivers/media/radio/wl128x/Kconfig"
+
+#
+# ISA drivers configuration
+#
+
+menuconfig V4L_RADIO_ISA_DRIVERS
+	bool "ISA radio devices"
+	depends on ISA
+	default n
+	---help---
+	  Say Y here to enable support for these ISA drivers.
+
+if V4L_RADIO_ISA_DRIVERS
+
 config RADIO_CADET
 	tristate "ADS Cadet AM/FM Tuner"
 	depends on ISA && VIDEO_V4L2
@@ -151,21 +307,6 @@
 	  following ports will be probed: 0x20c, 0x30c, 0x24c, 0x34c, 0x248 and
 	  0x28c.
 
-config RADIO_MAXIRADIO
-	tristate "Guillemot MAXI Radio FM 2000 radio"
-	depends on VIDEO_V4L2 && PCI
-	---help---
-	  Choose Y here if you have this radio card.  This card may also be
-	  found as Gemtek PCI FM.
-
-	  In order to control your radio card, you will need to use programs
-	  that are compatible with the Video For Linux API.  Information on
-	  this API and pointers to "v4l" programs may be found at
-	  <file:Documentation/video4linux/API.html>.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called radio-maxiradio.
-
 config RADIO_MIROPCM20
 	tristate "miroSOUND PCM20 radio"
 	depends on ISA && ISA_DMA_API && VIDEO_V4L2 && SND
@@ -316,130 +457,6 @@
 	help
 	  Enter the I/O port of your Zoltrix radio card.
 
-config I2C_SI4713
-	tristate "I2C driver for Silicon Labs Si4713 device"
-	depends on I2C && VIDEO_V4L2
-	---help---
-	  Say Y here if you want support to Si4713 I2C device.
-	  This device driver supports only i2c bus.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called si4713.
-
-config RADIO_SI4713
-	tristate "Silicon Labs Si4713 FM Radio Transmitter support"
-	depends on I2C && VIDEO_V4L2
-	select I2C_SI4713
-	---help---
-	  Say Y here if you want support to Si4713 FM Radio Transmitter.
-	  This device can transmit audio through FM. It can transmit
-	  RDS and RBDS signals as well. This module is the v4l2 radio
-	  interface for the i2c driver of this device.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called radio-si4713.
-
-config USB_DSBR
-	tristate "D-Link/GemTek USB FM radio support"
-	depends on USB && VIDEO_V4L2
-	---help---
-	  Say Y here if you want to connect this type of radio to your
-	  computer's USB port. Note that the audio is not digital, and
-	  you must connect the line out connector to a sound card or a
-	  set of speakers.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called dsbr100.
-
-config RADIO_SI470X
-	bool "Silicon Labs Si470x FM Radio Receiver support"
-	depends on VIDEO_V4L2
-
-source "drivers/media/radio/si470x/Kconfig"
-
-config USB_MR800
-	tristate "AverMedia MR 800 USB FM radio support"
-	depends on USB && VIDEO_V4L2
-	---help---
-	  Say Y here if you want to connect this type of radio to your
-	  computer's USB port. Note that the audio is not digital, and
-	  you must connect the line out connector to a sound card or a
-	  set of speakers.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called radio-mr800.
-
-config RADIO_TEA5764
-	tristate "TEA5764 I2C FM radio support"
-	depends on I2C && VIDEO_V4L2
-	---help---
-	  Say Y here if you want to use the TEA5764 FM chip found in
-	  EZX phones. This FM chip is present in EZX phones from Motorola,
-	  connected to internal pxa I2C bus.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called radio-tea5764.
-
-config RADIO_TEA5764_XTAL
-	bool "TEA5764 crystal reference"
-	depends on RADIO_TEA5764=y
-	default y
-	help
-	  Say Y here if TEA5764 have a 32768 Hz crystal in circuit, say N
-	  here if TEA5764 reference frequency is connected in FREQIN.
-
-config RADIO_SAA7706H
-	tristate "SAA7706H Car Radio DSP"
-	depends on I2C && VIDEO_V4L2
-	---help---
-	  Say Y here if you want to use the SAA7706H Car radio Digital
-	  Signal Processor, found for instance on the Russellville development
-	  board. On the russellville the device is connected to internal
-	  timberdale I2C bus.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called SAA7706H.
-
-config RADIO_TEF6862
-	tristate "TEF6862 Car Radio Enhanced Selectivity Tuner"
-	depends on I2C && VIDEO_V4L2
-	---help---
-	  Say Y here if you want to use the TEF6862 Car Radio Enhanced
-	  Selectivity Tuner, found for instance on the Russellville development
-	  board. On the russellville the device is connected to internal
-	  timberdale I2C bus.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called TEF6862.
-
-config RADIO_TIMBERDALE
-	tristate "Enable the Timberdale radio driver"
-	depends on MFD_TIMBERDALE && VIDEO_V4L2
-	depends on I2C	# for RADIO_SAA7706H
-	select RADIO_TEF6862
-	select RADIO_SAA7706H
-	---help---
-	  This is a kind of umbrella driver for the Radio Tuner and DSP
-	  found behind the Timberdale FPGA on the Russellville board.
-	  Enabling this driver will automatically select the DSP and tuner.
-
-config RADIO_WL1273
-	tristate "Texas Instruments WL1273 I2C FM Radio"
-	depends on I2C && VIDEO_V4L2
-	select MFD_WL1273_CORE
-	select FW_LOADER
-	---help---
-	  Choose Y here if you have this FM radio chip.
-
-	  In order to control your radio card, you will need to use programs
-	  that are compatible with the Video For Linux 2 API.  Information on
-	  this API and pointers to "v4l2" programs may be found at
-	  <file:Documentation/video4linux/API.html>.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called radio-wl1273.
-
-# TI's ST based wl128x FM radio
-source "drivers/media/radio/wl128x/Kconfig"
+endif # V4L_RADIO_ISA_DRIVERS
 
 endif # RADIO_ADAPTERS
diff --git a/drivers/media/radio/tef6862.c b/drivers/media/radio/tef6862.c
index 0991e19..3408685 100644
--- a/drivers/media/radio/tef6862.c
+++ b/drivers/media/radio/tef6862.c
@@ -118,9 +118,11 @@
 	i2cmsg[2] = pll & 0xff;
 
 	err = i2c_master_send(client, i2cmsg, sizeof(i2cmsg));
-	if (!err)
-		state->freq = f->frequency;
-	return err;
+	if (err != sizeof(i2cmsg))
+		return err < 0 ? err : -EIO;
+
+	state->freq = f->frequency;
+	return 0;
 }
 
 static int tef6862_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
diff --git a/drivers/media/radio/wl128x/fmdrv_v4l2.c b/drivers/media/radio/wl128x/fmdrv_v4l2.c
index 4f5c43d..077d369 100644
--- a/drivers/media/radio/wl128x/fmdrv_v4l2.c
+++ b/drivers/media/radio/wl128x/fmdrv_v4l2.c
@@ -84,6 +84,7 @@
 	struct fmdev *fmdev;
 
 	ret = copy_from_user(&rds, buf, sizeof(rds));
+	rds.text[sizeof(rds.text) - 1] = '\0';
 	fmdbg("(%d)type: %d, text %s, af %d\n",
 		   ret, rds.text_type, rds.text, rds.af_freq);
 	if (ret)
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index aeb7f43..4df4aff 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -87,6 +87,16 @@
 	   uses an IR protocol that is almost standard RC-5, but not quite,
 	   as it uses an additional bit).
 
+config IR_SANYO_DECODER
+	tristate "Enable IR raw decoder for the Sanyo protocol"
+	depends on RC_CORE
+	default y
+
+	---help---
+	   Enable this option if you have an infrared remote control which
+	   uses the Sanyo protocol (Sanyo, Aiwa, Chinon remotes),
+	   and you need software decoding support.
+
 config IR_MCE_KBD_DECODER
 	tristate "Enable IR raw decoder for the MCE keyboard/mouse protocol"
 	depends on RC_CORE
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index 2156e78..fb3dee2 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -10,6 +10,7 @@
 obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o
 obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
 obj-$(CONFIG_IR_RC5_SZ_DECODER) += ir-rc5-sz-decoder.o
+obj-$(CONFIG_IR_SANYO_DECODER) += ir-sanyo-decoder.o
 obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o
 obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
 
diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c
index 17f8db0..3c9431a 100644
--- a/drivers/media/rc/ir-nec-decoder.c
+++ b/drivers/media/rc/ir-nec-decoder.c
@@ -194,8 +194,8 @@
 		return 0;
 	}
 
-	IR_dprintk(1, "NEC decode failed at state %d (%uus %s)\n",
-		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+	IR_dprintk(1, "NEC decode failed at count %d state %d (%uus %s)\n",
+		   data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse));
 	data->state = STATE_INACTIVE;
 	return -EINVAL;
 }
diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c
index 2e5cd31..95e6309 100644
--- a/drivers/media/rc/ir-raw.c
+++ b/drivers/media/rc/ir-raw.c
@@ -357,6 +357,7 @@
 	load_rc6_decode();
 	load_jvc_decode();
 	load_sony_decode();
+	load_sanyo_decode();
 	load_mce_kbd_decode();
 	load_lirc_codec();
 
diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c
index 140fb67..4cfdd7f 100644
--- a/drivers/media/rc/ir-rc6-decoder.c
+++ b/drivers/media/rc/ir-rc6-decoder.c
@@ -18,24 +18,31 @@
 /*
  * This decoder currently supports:
  * RC6-0-16	(standard toggle bit in header)
+ * RC6-6A-20	(no toggle bit)
  * RC6-6A-24	(no toggle bit)
  * RC6-6A-32	(MCE version with toggle bit in body)
  */
 
-#define RC6_UNIT		444444	/* us */
+#define RC6_UNIT		444444	/* nanosecs */
 #define RC6_HEADER_NBITS	4	/* not including toggle bit */
 #define RC6_0_NBITS		16
-#define RC6_6A_SMALL_NBITS	24
-#define RC6_6A_LARGE_NBITS	32
+#define RC6_6A_32_NBITS		32
+#define RC6_6A_NBITS		128	/* Variable 8..128 */
 #define RC6_PREFIX_PULSE	(6 * RC6_UNIT)
 #define RC6_PREFIX_SPACE	(2 * RC6_UNIT)
 #define RC6_BIT_START		(1 * RC6_UNIT)
 #define RC6_BIT_END		(1 * RC6_UNIT)
 #define RC6_TOGGLE_START	(2 * RC6_UNIT)
 #define RC6_TOGGLE_END		(2 * RC6_UNIT)
+#define RC6_SUFFIX_SPACE	(6 * RC6_UNIT)
 #define RC6_MODE_MASK		0x07	/* for the header bits */
 #define RC6_STARTBIT_MASK	0x08	/* for the header bits */
 #define RC6_6A_MCE_TOGGLE_MASK	0x8000	/* for the body bits */
+#define RC6_6A_LCC_MASK		0xffff0000 /* RC6-6A-32 long customer code mask */
+#define RC6_6A_MCE_CC		0x800f0000 /* MCE customer code */
+#ifndef CHAR_BIT
+#define CHAR_BIT 8	/* Normally in <limits.h> */
+#endif
 
 enum rc6_mode {
 	RC6_MODE_0,
@@ -125,6 +132,7 @@
 			break;
 
 		data->state = STATE_HEADER_BIT_START;
+		data->header = 0;
 		return 0;
 
 	case STATE_HEADER_BIT_START:
@@ -171,20 +179,14 @@
 		data->state = STATE_BODY_BIT_START;
 		decrease_duration(&ev, RC6_TOGGLE_END);
 		data->count = 0;
+		data->body = 0;
 
 		switch (rc6_mode(data)) {
 		case RC6_MODE_0:
 			data->wanted_bits = RC6_0_NBITS;
 			break;
 		case RC6_MODE_6A:
-			/* This might look weird, but we basically
-			   check the value of the first body bit to
-			   determine the number of bits in mode 6A */
-			if ((!ev.pulse && !geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) ||
-			    geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
-				data->wanted_bits = RC6_6A_LARGE_NBITS;
-			else
-				data->wanted_bits = RC6_6A_SMALL_NBITS;
+			data->wanted_bits = RC6_6A_NBITS;
 			break;
 		default:
 			IR_dprintk(1, "RC6 unknown mode\n");
@@ -193,15 +195,21 @@
 		goto again;
 
 	case STATE_BODY_BIT_START:
-		if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2))
-			break;
-
-		data->body <<= 1;
-		if (ev.pulse)
-			data->body |= 1;
-		data->count++;
-		data->state = STATE_BODY_BIT_END;
-		return 0;
+		if (eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2)) {
+			/* Discard LSB's that won't fit in data->body */
+			if (data->count++ < CHAR_BIT * sizeof data->body) {
+				data->body <<= 1;
+				if (ev.pulse)
+					data->body |= 1;
+			}
+			data->state = STATE_BODY_BIT_END;
+			return 0;
+		} else if (RC6_MODE_6A == rc6_mode(data) && !ev.pulse &&
+				geq_margin(ev.duration, RC6_SUFFIX_SPACE, RC6_UNIT / 2)) {
+			data->state = STATE_FINISHED;
+			goto again;
+		}
+		break;
 
 	case STATE_BODY_BIT_END:
 		if (!is_transition(&ev, &dev->raw->prev_ev))
@@ -221,20 +229,27 @@
 
 		switch (rc6_mode(data)) {
 		case RC6_MODE_0:
-			scancode = data->body & 0xffff;
+			scancode = data->body;
 			toggle = data->toggle;
 			IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n",
 				   scancode, toggle);
 			break;
 		case RC6_MODE_6A:
-			if (data->wanted_bits == RC6_6A_LARGE_NBITS) {
-				toggle = data->body & RC6_6A_MCE_TOGGLE_MASK ? 1 : 0;
-				scancode = data->body & ~RC6_6A_MCE_TOGGLE_MASK;
-			} else {
-				toggle = 0;
-				scancode = data->body & 0xffffff;
+			if (data->count > CHAR_BIT * sizeof data->body) {
+				IR_dprintk(1, "RC6 too many (%u) data bits\n",
+					data->count);
+				goto out;
 			}
 
+			scancode = data->body;
+			if (data->count == RC6_6A_32_NBITS &&
+					(scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) {
+				/* MCE RC */
+				toggle = (scancode & RC6_6A_MCE_TOGGLE_MASK) ? 1 : 0;
+				scancode &= ~RC6_6A_MCE_TOGGLE_MASK;
+			} else {
+				toggle = 0;
+			}
 			IR_dprintk(1, "RC6(6A) scancode 0x%08x (toggle: %u)\n",
 				   scancode, toggle);
 			break;
diff --git a/drivers/media/rc/ir-sanyo-decoder.c b/drivers/media/rc/ir-sanyo-decoder.c
new file mode 100644
index 0000000..d38fbdd
--- /dev/null
+++ b/drivers/media/rc/ir-sanyo-decoder.c
@@ -0,0 +1,205 @@
+/* ir-sanyo-decoder.c - handle SANYO IR Pulse/Space protocol
+ *
+ * Copyright (C) 2011 by Mauro Carvalho Chehab <mchehab@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ * This protocol uses the NEC protocol timings. However, data is formatted as:
+ *	13 bits Custom Code
+ *	13 bits NOT(Custom Code)
+ *	8 bits Key data
+ *	8 bits NOT(Key data)
+ *
+ * According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon
+ * Information for this protocol is available at the Sanyo LC7461 datasheet.
+ */
+
+#include <linux/module.h>
+#include <linux/bitrev.h>
+#include "rc-core-priv.h"
+
+#define SANYO_NBITS		(13+13+8+8)
+#define SANYO_UNIT		562500  /* ns */
+#define SANYO_HEADER_PULSE	(16  * SANYO_UNIT)
+#define SANYO_HEADER_SPACE	(8   * SANYO_UNIT)
+#define SANYO_BIT_PULSE		(1   * SANYO_UNIT)
+#define SANYO_BIT_0_SPACE	(1   * SANYO_UNIT)
+#define SANYO_BIT_1_SPACE	(3   * SANYO_UNIT)
+#define SANYO_REPEAT_SPACE	(150 * SANYO_UNIT)
+#define	SANYO_TRAILER_PULSE	(1   * SANYO_UNIT)
+#define	SANYO_TRAILER_SPACE	(10  * SANYO_UNIT)	/* in fact, 42 */
+
+enum sanyo_state {
+	STATE_INACTIVE,
+	STATE_HEADER_SPACE,
+	STATE_BIT_PULSE,
+	STATE_BIT_SPACE,
+	STATE_TRAILER_PULSE,
+	STATE_TRAILER_SPACE,
+};
+
+/**
+ * ir_sanyo_decode() - Decode one SANYO pulse or space
+ * @dev:	the struct rc_dev descriptor of the device
+ * @duration:	the struct ir_raw_event descriptor of the pulse/space
+ *
+ * This function returns -EINVAL if the pulse violates the state machine
+ */
+static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev)
+{
+	struct sanyo_dec *data = &dev->raw->sanyo;
+	u32 scancode;
+	u8 address, not_address, command, not_command;
+
+	if (!(dev->raw->enabled_protocols & RC_TYPE_SANYO))
+		return 0;
+
+	if (!is_timing_event(ev)) {
+		if (ev.reset) {
+			IR_dprintk(1, "SANYO event reset received. reset to state 0\n");
+			data->state = STATE_INACTIVE;
+		}
+		return 0;
+	}
+
+	IR_dprintk(2, "SANYO decode started at state %d (%uus %s)\n",
+		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+
+	switch (data->state) {
+
+	case STATE_INACTIVE:
+		if (!ev.pulse)
+			break;
+
+		if (eq_margin(ev.duration, SANYO_HEADER_PULSE, SANYO_UNIT / 2)) {
+			data->count = 0;
+			data->state = STATE_HEADER_SPACE;
+			return 0;
+		}
+		break;
+
+
+	case STATE_HEADER_SPACE:
+		if (ev.pulse)
+			break;
+
+		if (eq_margin(ev.duration, SANYO_HEADER_SPACE, SANYO_UNIT / 2)) {
+			data->state = STATE_BIT_PULSE;
+			return 0;
+		}
+
+		break;
+
+	case STATE_BIT_PULSE:
+		if (!ev.pulse)
+			break;
+
+		if (!eq_margin(ev.duration, SANYO_BIT_PULSE, SANYO_UNIT / 2))
+			break;
+
+		data->state = STATE_BIT_SPACE;
+		return 0;
+
+	case STATE_BIT_SPACE:
+		if (ev.pulse)
+			break;
+
+		if (!data->count && geq_margin(ev.duration, SANYO_REPEAT_SPACE, SANYO_UNIT / 2)) {
+			if (!dev->keypressed) {
+				IR_dprintk(1, "SANYO discarding last key repeat: event after key up\n");
+			} else {
+				rc_repeat(dev);
+				IR_dprintk(1, "SANYO repeat last key\n");
+				data->state = STATE_INACTIVE;
+			}
+			return 0;
+		}
+
+		data->bits <<= 1;
+		if (eq_margin(ev.duration, SANYO_BIT_1_SPACE, SANYO_UNIT / 2))
+			data->bits |= 1;
+		else if (!eq_margin(ev.duration, SANYO_BIT_0_SPACE, SANYO_UNIT / 2))
+			break;
+		data->count++;
+
+		if (data->count == SANYO_NBITS)
+			data->state = STATE_TRAILER_PULSE;
+		else
+			data->state = STATE_BIT_PULSE;
+
+		return 0;
+
+	case STATE_TRAILER_PULSE:
+		if (!ev.pulse)
+			break;
+
+		if (!eq_margin(ev.duration, SANYO_TRAILER_PULSE, SANYO_UNIT / 2))
+			break;
+
+		data->state = STATE_TRAILER_SPACE;
+		return 0;
+
+	case STATE_TRAILER_SPACE:
+		if (ev.pulse)
+			break;
+
+		if (!geq_margin(ev.duration, SANYO_TRAILER_SPACE, SANYO_UNIT / 2))
+			break;
+
+		address     = bitrev16((data->bits >> 29) & 0x1fff) >> 3;
+		not_address = bitrev16((data->bits >> 16) & 0x1fff) >> 3;
+		command	    = bitrev8((data->bits >>  8) & 0xff);
+		not_command = bitrev8((data->bits >>  0) & 0xff);
+
+		if ((command ^ not_command) != 0xff) {
+			IR_dprintk(1, "SANYO checksum error: received 0x%08Lx\n",
+				   data->bits);
+			data->state = STATE_INACTIVE;
+			return 0;
+		}
+
+		scancode = address << 8 | command;
+		IR_dprintk(1, "SANYO scancode: 0x%06x\n", scancode);
+		rc_keydown(dev, scancode, 0);
+		data->state = STATE_INACTIVE;
+		return 0;
+	}
+
+	IR_dprintk(1, "SANYO decode failed at count %d state %d (%uus %s)\n",
+		   data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse));
+	data->state = STATE_INACTIVE;
+	return -EINVAL;
+}
+
+static struct ir_raw_handler sanyo_handler = {
+	.protocols	= RC_TYPE_SANYO,
+	.decode		= ir_sanyo_decode,
+};
+
+static int __init ir_sanyo_decode_init(void)
+{
+	ir_raw_handler_register(&sanyo_handler);
+
+	printk(KERN_INFO "IR SANYO protocol handler initialized\n");
+	return 0;
+}
+
+static void __exit ir_sanyo_decode_exit(void)
+{
+	ir_raw_handler_unregister(&sanyo_handler);
+}
+
+module_init(ir_sanyo_decode_init);
+module_exit(ir_sanyo_decode_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
+MODULE_DESCRIPTION("SANYO IR protocol decoder");
diff --git a/drivers/media/rc/keymaps/rc-hauppauge.c b/drivers/media/rc/keymaps/rc-hauppauge.c
index e51c616..929bbbc1 100644
--- a/drivers/media/rc/keymaps/rc-hauppauge.c
+++ b/drivers/media/rc/keymaps/rc-hauppauge.c
@@ -183,6 +183,57 @@
 	{ 0x1d3f, KEY_HOME },
 
 	/*
+	 * Keycodes for PT# R-005 remote bundled with Haupauge HVR-930C
+	 * Keycodes start with address = 0x1c
+	 */
+	{ 0x1c3b, KEY_GOTO },
+	{ 0x1c3d, KEY_POWER },
+
+	{ 0x1c14, KEY_UP },
+	{ 0x1c15, KEY_DOWN },
+	{ 0x1c16, KEY_LEFT },
+	{ 0x1c17, KEY_RIGHT },
+	{ 0x1c25, KEY_OK },
+
+	{ 0x1c00, KEY_0 },
+	{ 0x1c01, KEY_1 },
+	{ 0x1c02, KEY_2 },
+	{ 0x1c03, KEY_3 },
+	{ 0x1c04, KEY_4 },
+	{ 0x1c05, KEY_5 },
+	{ 0x1c06, KEY_6 },
+	{ 0x1c07, KEY_7 },
+	{ 0x1c08, KEY_8 },
+	{ 0x1c09, KEY_9 },
+
+	{ 0x1c1f, KEY_EXIT },	/* BACK */
+	{ 0x1c0d, KEY_MENU },
+	{ 0x1c1c, KEY_TV },
+
+	{ 0x1c10, KEY_VOLUMEUP },
+	{ 0x1c11, KEY_VOLUMEDOWN },
+
+	{ 0x1c20, KEY_CHANNELUP },
+	{ 0x1c21, KEY_CHANNELDOWN },
+
+	{ 0x1c0f, KEY_MUTE },
+	{ 0x1c12, KEY_PREVIOUS }, /* Prev */
+
+	{ 0x1c36, KEY_STOP },
+	{ 0x1c37, KEY_RECORD },
+
+	{ 0x1c24, KEY_LAST },           /* <|             */
+	{ 0x1c1e, KEY_NEXT },           /* >|             */
+
+	{ 0x1c0a, KEY_TEXT },
+	{ 0x1c0e, KEY_SUBTITLE },	/* CC */
+
+	{ 0x1c32, KEY_REWIND },
+	{ 0x1c30, KEY_PAUSE },
+	{ 0x1c35, KEY_PLAY },
+	{ 0x1c34, KEY_FASTFORWARD },
+
+	/*
 	 * Keycodes for the old Black Remote Controller
 	 * This one also uses RC-5 protocol
 	 * Keycodes start with address = 0x00
diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index c6ca870..b72f858 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -84,6 +84,11 @@
 		unsigned count;
 		unsigned wanted_bits;
 	} rc5_sz;
+	struct sanyo_dec {
+		int state;
+		unsigned count;
+		u64 bits;
+	} sanyo;
 	struct mce_kbd_dec {
 		struct input_dev *idev;
 		struct timer_list rx_timeout;
@@ -193,6 +198,13 @@
 static inline void load_sony_decode(void) { }
 #endif
 
+/* from ir-sanyo-decoder.c */
+#ifdef CONFIG_IR_SANYO_DECODER_MODULE
+#define load_sanyo_decode()	request_module("ir-sanyo-decoder")
+#else
+static inline void load_sanyo_decode(void) { }
+#endif
+
 /* from ir-mce_kbd-decoder.c */
 #ifdef CONFIG_IR_MCE_KBD_DECODER_MODULE
 #define load_mce_kbd_decode()	request_module("ir-mce_kbd-decoder")
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 29f9000..0ea55ea 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -736,6 +736,7 @@
 	{ RC_TYPE_JVC,		"jvc"		},
 	{ RC_TYPE_SONY,		"sony"		},
 	{ RC_TYPE_RC5_SZ,	"rc-5-sz"	},
+	{ RC_TYPE_SANYO,	"sanyo"		},
 	{ RC_TYPE_MCE_KBD,	"mce_kbd"	},
 	{ RC_TYPE_LIRC,		"lirc"		},
 	{ RC_TYPE_OTHER,	"other"		},
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
index 61287fc..9bff23c 100644
--- a/drivers/media/rc/redrat3.c
+++ b/drivers/media/rc/redrat3.c
@@ -286,12 +286,6 @@
 
 	rr3_ftr(rr3->dev, "Entering %s\n", __func__);
 
-	if (!rr3->det_enabled) {
-		dev_warn(rr3->dev, "not issuing async read, "
-			 "detector not enabled\n");
-		return;
-	}
-
 	memset(rr3->bulk_in_buf, 0, rr3->ep_in->wMaxPacketSize);
 	res = usb_submit_urb(rr3->read_urb, GFP_ATOMIC);
 	if (res)
@@ -827,6 +821,7 @@
 static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs)
 {
 	struct redrat3_dev *rr3;
+	int ret;
 
 	if (!urb)
 		return;
@@ -840,15 +835,13 @@
 
 	rr3_ftr(rr3->dev, "Entering %s\n", __func__);
 
-	if (!rr3->det_enabled) {
-		rr3_dbg(rr3->dev, "received a read callback but detector "
-			"disabled - ignoring\n");
-		return;
-	}
-
 	switch (urb->status) {
 	case 0:
-		redrat3_get_ir_data(rr3, urb->actual_length);
+		ret = redrat3_get_ir_data(rr3, urb->actual_length);
+		if (!ret) {
+			/* no error, prepare to read more */
+			redrat3_issue_async(rr3);
+		}
 		break;
 
 	case -ECONNRESET:
@@ -865,11 +858,6 @@
 		rr3->pkttype = 0;
 		break;
 	}
-
-	if (!rr3->transmitting)
-		redrat3_issue_async(rr3);
-	else
-		rr3_dbg(rr3->dev, "IR transmit in progress\n");
 }
 
 static void redrat3_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
@@ -896,21 +884,24 @@
 	return (u16)(65536 - (mult / mod_freq));
 }
 
-static int redrat3_set_tx_carrier(struct rc_dev *dev, u32 carrier)
+static int redrat3_set_tx_carrier(struct rc_dev *rcdev, u32 carrier)
 {
-	struct redrat3_dev *rr3 = dev->priv;
+	struct redrat3_dev *rr3 = rcdev->priv;
+	struct device *dev = rr3->dev;
 
+	rr3_dbg(dev, "Setting modulation frequency to %u", carrier);
 	rr3->carrier = carrier;
 
 	return carrier;
 }
 
-static int redrat3_transmit_ir(struct rc_dev *rcdev, int *txbuf, u32 n)
+static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf,
+				unsigned count)
 {
 	struct redrat3_dev *rr3 = rcdev->priv;
 	struct device *dev = rr3->dev;
 	struct redrat3_signal_header header;
-	int i, j, count, ret, ret_len, offset;
+	int i, j, ret, ret_len, offset;
 	int lencheck, cur_sample_len, pipe;
 	char *buffer = NULL, *sigdata = NULL;
 	int *sample_lens = NULL;
@@ -928,20 +919,13 @@
 		return -EAGAIN;
 	}
 
-	count = n / sizeof(int);
 	if (count > (RR3_DRIVER_MAXLENS * 2))
 		return -EINVAL;
 
+	/* rr3 will disable rc detector on transmit */
+	rr3->det_enabled = false;
 	rr3->transmitting = true;
 
-	redrat3_disable_detector(rr3);
-
-	if (rr3->det_enabled) {
-		dev_err(dev, "%s: cannot tx while rx is enabled\n", __func__);
-		ret = -EIO;
-		goto out;
-	}
-
 	sample_lens = kzalloc(sizeof(int) * RR3_DRIVER_MAXLENS, GFP_KERNEL);
 	if (!sample_lens) {
 		ret = -ENOMEM;
@@ -1055,7 +1039,7 @@
 	if (ret < 0)
 		dev_err(dev, "Error: control msg send failed, rc %d\n", ret);
 	else
-		ret = n;
+		ret = count;
 
 out:
 	kfree(sample_lens);
@@ -1063,8 +1047,8 @@
 	kfree(sigdata);
 
 	rr3->transmitting = false;
-
-	redrat3_enable_detector(rr3);
+	/* rr3 re-enables rc detector because it was enabled before */
+	rr3->det_enabled = true;
 
 	return ret;
 }
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index b303a3f..0e4d241 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -533,6 +533,13 @@
 	  This is a driver for the ADP1653 flash controller. It is used for
 	  example in Nokia N900.
 
+config VIDEO_AS3645A
+	tristate "AS3645A flash driver support"
+	depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
+	---help---
+	  This is a driver for the AS3645A and LM3555 flash controllers. It has
+	  build in control for flash, torch and indicator LEDs.
+
 comment "Video improvement chips"
 
 config VIDEO_UPD64031A
@@ -580,6 +587,270 @@
 
 endmenu # encoder / decoder chips
 
+config VIDEO_VIVI
+	tristate "Virtual Video Driver"
+	depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64
+	depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
+	select FONT_8x16
+	select VIDEOBUF2_VMALLOC
+	default n
+	---help---
+	  Enables a virtual video driver. This device shows a color bar
+	  and a timestamp, as a real device would generate by using V4L2
+	  api.
+	  Say Y here if you want to test video apps or debug V4L devices.
+	  In doubt, say N.
+
+#
+# USB Multimedia device configuration
+#
+
+menuconfig V4L_USB_DRIVERS
+	bool "V4L USB devices"
+	depends on USB
+	default y
+
+if V4L_USB_DRIVERS
+
+source "drivers/media/video/uvc/Kconfig"
+
+source "drivers/media/video/gspca/Kconfig"
+
+source "drivers/media/video/pvrusb2/Kconfig"
+
+source "drivers/media/video/hdpvr/Kconfig"
+
+source "drivers/media/video/em28xx/Kconfig"
+
+source "drivers/media/video/tlg2300/Kconfig"
+
+source "drivers/media/video/cx231xx/Kconfig"
+
+source "drivers/media/video/tm6000/Kconfig"
+
+source "drivers/media/video/usbvision/Kconfig"
+
+source "drivers/media/video/et61x251/Kconfig"
+
+source "drivers/media/video/sn9c102/Kconfig"
+
+source "drivers/media/video/pwc/Kconfig"
+
+source "drivers/media/video/cpia2/Kconfig"
+
+config USB_ZR364XX
+	tristate "USB ZR364XX Camera support"
+	depends on VIDEO_V4L2
+	select VIDEOBUF_GEN
+	select VIDEOBUF_VMALLOC
+	---help---
+	  Say Y here if you want to connect this type of camera to your
+	  computer's USB port.
+	  See <file:Documentation/video4linux/zr364xx.txt> for more info
+	  and list of supported cameras.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called zr364xx.
+
+config USB_STKWEBCAM
+	tristate "USB Syntek DC1125 Camera support"
+	depends on VIDEO_V4L2 && EXPERIMENTAL
+	---help---
+	  Say Y here if you want to use this type of camera.
+	  Supported devices are typically found in some Asus laptops,
+	  with USB id 174f:a311 and 05e1:0501. Other Syntek cameras
+	  may be supported by the stk11xx driver, from which this is
+	  derived, see <http://sourceforge.net/projects/syntekdriver/>
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called stkwebcam.
+
+config USB_S2255
+	tristate "USB Sensoray 2255 video capture device"
+	depends on VIDEO_V4L2
+	select VIDEOBUF_VMALLOC
+	default n
+	help
+	  Say Y here if you want support for the Sensoray 2255 USB device.
+	  This driver can be compiled as a module, called s2255drv.
+
+endif # V4L_USB_DRIVERS
+
+#
+# PCI drivers configuration
+#
+
+menuconfig V4L_PCI_DRIVERS
+	bool "V4L PCI(e) devices"
+	depends on PCI
+	default y
+	---help---
+	  Say Y here to enable support for these PCI(e) drivers.
+
+if V4L_PCI_DRIVERS
+
+source "drivers/media/video/au0828/Kconfig"
+
+source "drivers/media/video/bt8xx/Kconfig"
+
+source "drivers/media/video/cx18/Kconfig"
+
+source "drivers/media/video/cx23885/Kconfig"
+
+source "drivers/media/video/cx25821/Kconfig"
+
+source "drivers/media/video/cx88/Kconfig"
+
+config VIDEO_HEXIUM_GEMINI
+	tristate "Hexium Gemini frame grabber"
+	depends on PCI && VIDEO_V4L2 && I2C
+	select VIDEO_SAA7146_VV
+	---help---
+	  This is a video4linux driver for the Hexium Gemini frame
+	  grabber card by Hexium. Please note that the Gemini Dual
+	  card is *not* fully supported.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called hexium_gemini.
+
+config VIDEO_HEXIUM_ORION
+	tristate "Hexium HV-PCI6 and Orion frame grabber"
+	depends on PCI && VIDEO_V4L2 && I2C
+	select VIDEO_SAA7146_VV
+	---help---
+	  This is a video4linux driver for the Hexium HV-PCI6 and
+	  Orion frame grabber cards by Hexium.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called hexium_orion.
+
+source "drivers/media/video/ivtv/Kconfig"
+
+config VIDEO_MEYE
+	tristate "Sony Vaio Picturebook Motion Eye Video For Linux"
+	depends on PCI && SONY_LAPTOP && VIDEO_V4L2
+	---help---
+	  This is the video4linux driver for the Motion Eye camera found
+	  in the Vaio Picturebook laptops. Please read the material in
+	  <file:Documentation/video4linux/meye.txt> for more information.
+
+	  If you say Y or M here, you need to say Y or M to "Sony Laptop
+	  Extras" in the misc device section.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called meye.
+
+config VIDEO_MXB
+	tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
+	depends on PCI && VIDEO_V4L2 && I2C
+	select VIDEO_SAA7146_VV
+	select VIDEO_TUNER
+	select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
+	select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO
+	select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO
+	select VIDEO_TEA6420 if VIDEO_HELPER_CHIPS_AUTO
+	---help---
+	  This is a video4linux driver for the 'Multimedia eXtension Board'
+	  TV card by Siemens-Nixdorf.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called mxb.
+
+source "drivers/media/video/saa7134/Kconfig"
+
+source "drivers/media/video/saa7164/Kconfig"
+
+source "drivers/media/video/zoran/Kconfig"
+
+endif # V4L_PCI_DRIVERS
+
+#
+# ISA & parallel port drivers configuration
+#
+
+menuconfig V4L_ISA_PARPORT_DRIVERS
+	bool "V4L ISA and parallel port devices"
+	depends on ISA || PARPORT
+	default n
+	---help---
+	  Say Y here to enable support for these ISA and parallel port drivers.
+
+if V4L_ISA_PARPORT_DRIVERS
+
+config VIDEO_BWQCAM
+	tristate "Quickcam BW Video For Linux"
+	depends on PARPORT && VIDEO_V4L2
+	help
+	  Say Y have if you the black and white version of the QuickCam
+	  camera. See the next option for the color version.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called bw-qcam.
+
+config VIDEO_CQCAM
+	tristate "QuickCam Colour Video For Linux"
+	depends on PARPORT && VIDEO_V4L2
+	help
+	  This is the video4linux driver for the colour version of the
+	  Connectix QuickCam.  If you have one of these cameras, say Y here,
+	  otherwise say N.  This driver does not work with the original
+	  monochrome QuickCam, QuickCam VC or QuickClip.  It is also available
+	  as a module (c-qcam).
+	  Read <file:Documentation/video4linux/CQcam.txt> for more information.
+
+config VIDEO_PMS
+	tristate "Mediavision Pro Movie Studio Video For Linux"
+	depends on ISA && VIDEO_V4L2
+	help
+	  Say Y if you have the ISA Mediavision Pro Movie Studio
+	  capture card.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called pms.
+
+config VIDEO_W9966
+	tristate "W9966CF Webcam (FlyCam Supra and others) Video For Linux"
+	depends on PARPORT_1284 && PARPORT && VIDEO_V4L2
+	help
+	  Video4linux driver for Winbond's w9966 based Webcams.
+	  Currently tested with the LifeView FlyCam Supra.
+	  If you have one of these cameras, say Y here
+	  otherwise say N.
+	  This driver is also available as a module (w9966).
+
+	  Check out <file:Documentation/video4linux/w9966.txt> for more
+	  information.
+
+endif # V4L_ISA_PARPORT_DRIVERS
+
+menuconfig V4L_PLATFORM_DRIVERS
+	bool "V4L platform devices"
+	default n
+	---help---
+	  Say Y here to enable support for platform-specific V4L drivers.
+
+if V4L_PLATFORM_DRIVERS
+
+source "drivers/media/video/marvell-ccic/Kconfig"
+
+config VIDEO_VIA_CAMERA
+	tristate "VIAFB camera controller support"
+	depends on FB_VIA
+	select VIDEOBUF_DMA_SG
+	select VIDEO_OV7670
+	help
+	   Driver support for the integrated camera controller in VIA
+	   Chrome9 chipsets.  Currently only tested on OLPC xo-1.5 systems
+	   with ov7670 sensors.
+
+#
+# Platform multimedia device configuration
+#
+
+source "drivers/media/video/davinci/Kconfig"
+
+source "drivers/media/video/omap/Kconfig"
+
 config VIDEO_SH_VOU
 	tristate "SuperH VOU video output driver"
 	depends on VIDEO_DEV && ARCH_SHMOBILE
@@ -599,136 +870,6 @@
 	  Say Y here if you want to enable VIU device on MPC5121e Rev2+.
 	  In doubt, say N.
 
-config VIDEO_VIVI
-	tristate "Virtual Video Driver"
-	depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64
-	depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
-	select FONT_8x16
-	select VIDEOBUF2_VMALLOC
-	default n
-	---help---
-	  Enables a virtual video driver. This device shows a color bar
-	  and a timestamp, as a real device would generate by using V4L2
-	  api.
-	  Say Y here if you want to test video apps or debug V4L devices.
-	  In doubt, say N.
-
-source "drivers/media/video/davinci/Kconfig"
-
-source "drivers/media/video/omap/Kconfig"
-
-source "drivers/media/video/bt8xx/Kconfig"
-
-config VIDEO_PMS
-	tristate "Mediavision Pro Movie Studio Video For Linux"
-	depends on ISA && VIDEO_V4L2
-	help
-	  Say Y if you have such a thing.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called pms.
-
-config VIDEO_BWQCAM
-	tristate "Quickcam BW Video For Linux"
-	depends on PARPORT && VIDEO_V4L2
-	help
-	  Say Y have if you the black and white version of the QuickCam
-	  camera. See the next option for the color version.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called bw-qcam.
-
-config VIDEO_CQCAM
-	tristate "QuickCam Colour Video For Linux (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && PARPORT && VIDEO_V4L2
-	help
-	  This is the video4linux driver for the colour version of the
-	  Connectix QuickCam.  If you have one of these cameras, say Y here,
-	  otherwise say N.  This driver does not work with the original
-	  monochrome QuickCam, QuickCam VC or QuickClip.  It is also available
-	  as a module (c-qcam).
-	  Read <file:Documentation/video4linux/CQcam.txt> for more information.
-
-config VIDEO_W9966
-	tristate "W9966CF Webcam (FlyCam Supra and others) Video For Linux"
-	depends on PARPORT_1284 && PARPORT && VIDEO_V4L2
-	help
-	  Video4linux driver for Winbond's w9966 based Webcams.
-	  Currently tested with the LifeView FlyCam Supra.
-	  If you have one of these cameras, say Y here
-	  otherwise say N.
-	  This driver is also available as a module (w9966).
-
-	  Check out <file:Documentation/video4linux/w9966.txt> for more
-	  information.
-
-source "drivers/media/video/cpia2/Kconfig"
-
-config VIDEO_VINO
-	tristate "SGI Vino Video For Linux (EXPERIMENTAL)"
-	depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L2
-	select VIDEO_SAA7191 if VIDEO_HELPER_CHIPS_AUTO
-	help
-	  Say Y here to build in support for the Vino video input system found
-	  on SGI Indy machines.
-
-source "drivers/media/video/zoran/Kconfig"
-
-config VIDEO_MEYE
-	tristate "Sony Vaio Picturebook Motion Eye Video For Linux"
-	depends on PCI && SONY_LAPTOP && VIDEO_V4L2
-	---help---
-	  This is the video4linux driver for the Motion Eye camera found
-	  in the Vaio Picturebook laptops. Please read the material in
-	  <file:Documentation/video4linux/meye.txt> for more information.
-
-	  If you say Y or M here, you need to say Y or M to "Sony Laptop
-	  Extras" in the misc device section.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called meye.
-
-source "drivers/media/video/saa7134/Kconfig"
-
-config VIDEO_MXB
-	tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
-	depends on PCI && VIDEO_V4L2 && I2C
-	select VIDEO_SAA7146_VV
-	select VIDEO_TUNER
-	select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
-	select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO
-	select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO
-	select VIDEO_TEA6420 if VIDEO_HELPER_CHIPS_AUTO
-	---help---
-	  This is a video4linux driver for the 'Multimedia eXtension Board'
-	  TV card by Siemens-Nixdorf.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called mxb.
-
-config VIDEO_HEXIUM_ORION
-	tristate "Hexium HV-PCI6 and Orion frame grabber"
-	depends on PCI && VIDEO_V4L2 && I2C
-	select VIDEO_SAA7146_VV
-	---help---
-	  This is a video4linux driver for the Hexium HV-PCI6 and
-	  Orion frame grabber cards by Hexium.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called hexium_orion.
-
-config VIDEO_HEXIUM_GEMINI
-	tristate "Hexium Gemini frame grabber"
-	depends on PCI && VIDEO_V4L2 && I2C
-	select VIDEO_SAA7146_VV
-	---help---
-	  This is a video4linux driver for the Hexium Gemini frame
-	  grabber card by Hexium. Please note that the Gemini Dual
-	  card is *not* fully supported.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called hexium_gemini.
-
 config VIDEO_TIMBERDALE
 	tristate "Support for timberdale Video In/LogiWIN"
 	depends on VIDEO_V4L2 && I2C && DMADEVICES
@@ -739,21 +880,13 @@
 	---help---
 	  Add support for the Video In peripherial of the timberdale FPGA.
 
-source "drivers/media/video/cx88/Kconfig"
-
-source "drivers/media/video/cx23885/Kconfig"
-
-source "drivers/media/video/cx25821/Kconfig"
-
-source "drivers/media/video/au0828/Kconfig"
-
-source "drivers/media/video/ivtv/Kconfig"
-
-source "drivers/media/video/cx18/Kconfig"
-
-source "drivers/media/video/saa7164/Kconfig"
-
-source "drivers/media/video/marvell-ccic/Kconfig"
+config VIDEO_VINO
+	tristate "SGI Vino Video For Linux"
+	depends on I2C && SGI_IP22 && VIDEO_V4L2
+	select VIDEO_SAA7191 if VIDEO_HELPER_CHIPS_AUTO
+	help
+	  Say Y here to build in support for the Vino video input system found
+	  on SGI Indy machines.
 
 config VIDEO_M32R_AR
 	tristate "AR devices"
@@ -774,16 +907,6 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called arv.
 
-config VIDEO_VIA_CAMERA
-	tristate "VIAFB camera controller support"
-	depends on FB_VIA
-	select VIDEOBUF_DMA_SG
-	select VIDEO_OV7670
-	help
-	   Driver support for the integrated camera controller in VIA
-	   Chrome9 chipsets.  Currently only tested on OLPC xo-1.5 systems
-	   with ov7670 sensors.
-
 config VIDEO_OMAP3
 	tristate "OMAP 3 Camera support (EXPERIMENTAL)"
 	depends on OMAP_IOVMM && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && ARCH_OMAP3 && EXPERIMENTAL
@@ -1002,78 +1125,7 @@
 
 source "drivers/media/video/s5p-tv/Kconfig"
 
-#
-# USB Multimedia device configuration
-#
-
-menuconfig V4L_USB_DRIVERS
-	bool "V4L USB devices"
-	depends on USB
-	default y
-
-if V4L_USB_DRIVERS && USB
-
-source "drivers/media/video/uvc/Kconfig"
-
-source "drivers/media/video/gspca/Kconfig"
-
-source "drivers/media/video/pvrusb2/Kconfig"
-
-source "drivers/media/video/hdpvr/Kconfig"
-
-source "drivers/media/video/em28xx/Kconfig"
-
-source "drivers/media/video/tlg2300/Kconfig"
-
-source "drivers/media/video/cx231xx/Kconfig"
-
-source "drivers/media/video/tm6000/Kconfig"
-
-source "drivers/media/video/usbvision/Kconfig"
-
-source "drivers/media/video/et61x251/Kconfig"
-
-source "drivers/media/video/sn9c102/Kconfig"
-
-source "drivers/media/video/pwc/Kconfig"
-
-config USB_ZR364XX
-	tristate "USB ZR364XX Camera support"
-	depends on VIDEO_V4L2
-	select VIDEOBUF_GEN
-	select VIDEOBUF_VMALLOC
-	---help---
-	  Say Y here if you want to connect this type of camera to your
-	  computer's USB port.
-	  See <file:Documentation/video4linux/zr364xx.txt> for more info
-	  and list of supported cameras.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called zr364xx.
-
-config USB_STKWEBCAM
-	tristate "USB Syntek DC1125 Camera support"
-	depends on VIDEO_V4L2 && EXPERIMENTAL
-	---help---
-	  Say Y here if you want to use this type of camera.
-	  Supported devices are typically found in some Asus laptops,
-	  with USB id 174f:a311 and 05e1:0501. Other Syntek cameras
-	  may be supported by the stk11xx driver, from which this is
-	  derived, see <http://sourceforge.net/projects/syntekdriver/>
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called stkwebcam.
-
-config USB_S2255
-	tristate "USB Sensoray 2255 video capture device"
-	depends on VIDEO_V4L2
-	select VIDEOBUF_VMALLOC
-	default n
-	help
-	  Say Y here if you want support for the Sensoray 2255 USB device.
-	  This driver can be compiled as a module, called s2255drv.
-
-endif # V4L_USB_DRIVERS
+endif # V4L_PLATFORM_DRIVERS
 endif # VIDEO_CAPTURE_DRIVERS
 
 menuconfig V4L_MEM2MEM_DRIVERS
@@ -1098,6 +1150,15 @@
 	  This is a virtual test device for the memory-to-memory driver
 	  framework.
 
+config VIDEO_SAMSUNG_S5P_G2D
+	tristate "Samsung S5P and EXYNOS4 G2D 2d graphics accelerator driver"
+	depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
+	select VIDEOBUF2_DMA_CONTIG
+	select V4L2_MEM2MEM_DEV
+	default n
+	---help---
+	  This is a v4l2 driver for Samsung S5P and EXYNOS4 G2D
+	  2d graphics accelerator.
 
 config VIDEO_SAMSUNG_S5P_MFC
 	tristate "Samsung S5P MFC 5.1 Video Codec"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 117f9c4..86aabd6 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -74,6 +74,7 @@
 obj-$(CONFIG_VIDEO_M5MOLS)	+= m5mols/
 obj-$(CONFIG_VIDEO_S5K6AA)	+= s5k6aa.o
 obj-$(CONFIG_VIDEO_ADP1653)	+= adp1653.o
+obj-$(CONFIG_VIDEO_AS3645A)	+= as3645a.o
 
 obj-$(CONFIG_SOC_CAMERA_IMX074)		+= imx074.o
 obj-$(CONFIG_SOC_CAMERA_MT9M001)	+= mt9m001.o
@@ -180,6 +181,8 @@
 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC)	+= s5p-mfc/
 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_TV)	+= s5p-tv/
 
+obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D)	+= s5p-g2d/
+
 obj-$(CONFIG_ARCH_DAVINCI)		+= davinci/
 
 obj-$(CONFIG_VIDEO_SH_VOU)		+= sh_vou.o
diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c
index 23ba5c3..879f1d8 100644
--- a/drivers/media/video/adv7170.c
+++ b/drivers/media/video/adv7170.c
@@ -64,6 +64,11 @@
 
 static char *inputs[] = { "pass_through", "play_back" };
 
+static enum v4l2_mbus_pixelcode adv7170_codes[] = {
+	V4L2_MBUS_FMT_UYVY8_2X8,
+	V4L2_MBUS_FMT_UYVY8_1X16,
+};
+
 /* ----------------------------------------------------------------------- */
 
 static inline int adv7170_write(struct v4l2_subdev *sd, u8 reg, u8 value)
@@ -258,6 +263,60 @@
 	return 0;
 }
 
+static int adv7170_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
+				enum v4l2_mbus_pixelcode *code)
+{
+	if (index >= ARRAY_SIZE(adv7170_codes))
+		return -EINVAL;
+
+	*code = adv7170_codes[index];
+	return 0;
+}
+
+static int adv7170_g_fmt(struct v4l2_subdev *sd,
+				struct v4l2_mbus_framefmt *mf)
+{
+	u8 val = adv7170_read(sd, 0x7);
+
+	if ((val & 0x40) == (1 << 6))
+		mf->code = V4L2_MBUS_FMT_UYVY8_1X16;
+	else
+		mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
+
+	mf->colorspace  = V4L2_COLORSPACE_SMPTE170M;
+	mf->width       = 0;
+	mf->height      = 0;
+	mf->field       = V4L2_FIELD_ANY;
+
+	return 0;
+}
+
+static int adv7170_s_fmt(struct v4l2_subdev *sd,
+				struct v4l2_mbus_framefmt *mf)
+{
+	u8 val = adv7170_read(sd, 0x7);
+	int ret;
+
+	switch (mf->code) {
+	case V4L2_MBUS_FMT_UYVY8_2X8:
+		val &= ~0x40;
+		break;
+
+	case V4L2_MBUS_FMT_UYVY8_1X16:
+		val |= 0x40;
+		break;
+
+	default:
+		v4l2_dbg(1, debug, sd,
+			"illegal v4l2_mbus_framefmt code: %d\n", mf->code);
+		return -EINVAL;
+	}
+
+	ret = adv7170_write(sd, 0x7, val);
+
+	return ret;
+}
+
 static int adv7170_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -274,6 +333,9 @@
 static const struct v4l2_subdev_video_ops adv7170_video_ops = {
 	.s_std_output = adv7170_s_std_output,
 	.s_routing = adv7170_s_routing,
+	.s_mbus_fmt = adv7170_s_fmt,
+	.g_mbus_fmt = adv7170_g_fmt,
+	.enum_mbus_fmt  = adv7170_enum_fmt,
 };
 
 static const struct v4l2_subdev_ops adv7170_ops = {
diff --git a/drivers/media/video/as3645a.c b/drivers/media/video/as3645a.c
new file mode 100644
index 0000000..ec859a5
--- /dev/null
+++ b/drivers/media/video/as3645a.c
@@ -0,0 +1,904 @@
+/*
+ * drivers/media/video/as3645a.c - AS3645A and LM3555 flash controllers driver
+ *
+ * Copyright (C) 2008-2011 Nokia Corporation
+ * Copyright (c) 2011, Intel Corporation.
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * TODO:
+ * - Check hardware FSTROBE control when sensor driver add support for this
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+
+#include <media/as3645a.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+
+#define AS_TIMER_MS_TO_CODE(t)			(((t) - 100) / 50)
+#define AS_TIMER_CODE_TO_MS(c)			(50 * (c) + 100)
+
+/* Register definitions */
+
+/* Read-only Design info register: Reset state: xxxx 0001 */
+#define AS_DESIGN_INFO_REG			0x00
+#define AS_DESIGN_INFO_FACTORY(x)		(((x) >> 4))
+#define AS_DESIGN_INFO_MODEL(x)			((x) & 0x0f)
+
+/* Read-only Version control register: Reset state: 0000 0000
+ * for first engineering samples
+ */
+#define AS_VERSION_CONTROL_REG			0x01
+#define AS_VERSION_CONTROL_RFU(x)		(((x) >> 4))
+#define AS_VERSION_CONTROL_VERSION(x)		((x) & 0x0f)
+
+/* Read / Write	(Indicator and timer register): Reset state: 0000 1111 */
+#define AS_INDICATOR_AND_TIMER_REG		0x02
+#define AS_INDICATOR_AND_TIMER_TIMEOUT_SHIFT	0
+#define AS_INDICATOR_AND_TIMER_VREF_SHIFT	4
+#define AS_INDICATOR_AND_TIMER_INDICATOR_SHIFT	6
+
+/* Read / Write	(Current set register): Reset state: 0110 1001 */
+#define AS_CURRENT_SET_REG			0x03
+#define AS_CURRENT_ASSIST_LIGHT_SHIFT		0
+#define AS_CURRENT_LED_DET_ON			(1 << 3)
+#define AS_CURRENT_FLASH_CURRENT_SHIFT		4
+
+/* Read / Write	(Control register): Reset state: 1011 0100 */
+#define AS_CONTROL_REG				0x04
+#define AS_CONTROL_MODE_SETTING_SHIFT		0
+#define AS_CONTROL_STROBE_ON			(1 << 2)
+#define AS_CONTROL_OUT_ON			(1 << 3)
+#define AS_CONTROL_EXT_TORCH_ON			(1 << 4)
+#define AS_CONTROL_STROBE_TYPE_EDGE		(0 << 5)
+#define AS_CONTROL_STROBE_TYPE_LEVEL		(1 << 5)
+#define AS_CONTROL_COIL_PEAK_SHIFT		6
+
+/* Read only (D3 is read / write) (Fault and info): Reset state: 0000 x000 */
+#define AS_FAULT_INFO_REG			0x05
+#define AS_FAULT_INFO_INDUCTOR_PEAK_LIMIT	(1 << 1)
+#define AS_FAULT_INFO_INDICATOR_LED		(1 << 2)
+#define AS_FAULT_INFO_LED_AMOUNT		(1 << 3)
+#define AS_FAULT_INFO_TIMEOUT			(1 << 4)
+#define AS_FAULT_INFO_OVER_TEMPERATURE		(1 << 5)
+#define AS_FAULT_INFO_SHORT_CIRCUIT		(1 << 6)
+#define AS_FAULT_INFO_OVER_VOLTAGE		(1 << 7)
+
+/* Boost register */
+#define AS_BOOST_REG				0x0d
+#define AS_BOOST_CURRENT_DISABLE		(0 << 0)
+#define AS_BOOST_CURRENT_ENABLE			(1 << 0)
+
+/* Password register is used to unlock boost register writing */
+#define AS_PASSWORD_REG				0x0f
+#define AS_PASSWORD_UNLOCK_VALUE		0x55
+
+enum as_mode {
+	AS_MODE_EXT_TORCH = 0 << AS_CONTROL_MODE_SETTING_SHIFT,
+	AS_MODE_INDICATOR = 1 << AS_CONTROL_MODE_SETTING_SHIFT,
+	AS_MODE_ASSIST = 2 << AS_CONTROL_MODE_SETTING_SHIFT,
+	AS_MODE_FLASH = 3 << AS_CONTROL_MODE_SETTING_SHIFT,
+};
+
+/*
+ * struct as3645a
+ *
+ * @subdev:		V4L2 subdev
+ * @pdata:		Flash platform data
+ * @power_lock:		Protects power_count
+ * @power_count:	Power reference count
+ * @led_mode:		V4L2 flash LED mode
+ * @timeout:		Flash timeout in microseconds
+ * @flash_current:	Flash current (0=200mA ... 15=500mA). Maximum
+ *			values are 400mA for two LEDs and 500mA for one LED.
+ * @assist_current:	Torch/Assist light current (0=20mA, 1=40mA ... 7=160mA)
+ * @indicator_current:	Indicator LED current (0=0mA, 1=2.5mA ... 4=10mA)
+ * @strobe_source:	Flash strobe source (software or external)
+ */
+struct as3645a {
+	struct v4l2_subdev subdev;
+	const struct as3645a_platform_data *pdata;
+
+	struct mutex power_lock;
+	int power_count;
+
+	/* Controls */
+	struct v4l2_ctrl_handler ctrls;
+
+	enum v4l2_flash_led_mode led_mode;
+	unsigned int timeout;
+	u8 flash_current;
+	u8 assist_current;
+	u8 indicator_current;
+	enum v4l2_flash_strobe_source strobe_source;
+};
+
+#define to_as3645a(sd) container_of(sd, struct as3645a, subdev)
+
+/* Return negative errno else zero on success */
+static int as3645a_write(struct as3645a *flash, u8 addr, u8 val)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
+	int rval;
+
+	rval = i2c_smbus_write_byte_data(client, addr, val);
+
+	dev_dbg(&client->dev, "Write Addr:%02X Val:%02X %s\n", addr, val,
+		rval < 0 ? "fail" : "ok");
+
+	return rval;
+}
+
+/* Return negative errno else a data byte received from the device. */
+static int as3645a_read(struct as3645a *flash, u8 addr)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
+	int rval;
+
+	rval = i2c_smbus_read_byte_data(client, addr);
+
+	dev_dbg(&client->dev, "Read Addr:%02X Val:%02X %s\n", addr, rval,
+		rval < 0 ? "fail" : "ok");
+
+	return rval;
+}
+
+/* -----------------------------------------------------------------------------
+ * Hardware configuration and trigger
+ */
+
+/*
+ * as3645a_set_config - Set flash configuration registers
+ * @flash: The flash
+ *
+ * Configure the hardware with flash, assist and indicator currents, as well as
+ * flash timeout.
+ *
+ * Return 0 on success, or a negative error code if an I2C communication error
+ * occurred.
+ */
+static int as3645a_set_config(struct as3645a *flash)
+{
+	int ret;
+	u8 val;
+
+	val = (flash->flash_current << AS_CURRENT_FLASH_CURRENT_SHIFT)
+	    | (flash->assist_current << AS_CURRENT_ASSIST_LIGHT_SHIFT)
+	    | AS_CURRENT_LED_DET_ON;
+
+	ret = as3645a_write(flash, AS_CURRENT_SET_REG, val);
+	if (ret < 0)
+		return ret;
+
+	val = AS_TIMER_MS_TO_CODE(flash->timeout / 1000)
+		    << AS_INDICATOR_AND_TIMER_TIMEOUT_SHIFT;
+
+	val |= (flash->pdata->vref << AS_INDICATOR_AND_TIMER_VREF_SHIFT)
+	    |  ((flash->indicator_current ? flash->indicator_current - 1 : 0)
+		 << AS_INDICATOR_AND_TIMER_INDICATOR_SHIFT);
+
+	return as3645a_write(flash, AS_INDICATOR_AND_TIMER_REG, val);
+}
+
+/*
+ * as3645a_set_control - Set flash control register
+ * @flash: The flash
+ * @mode: Desired output mode
+ * @on: Desired output state
+ *
+ * Configure the hardware with output mode and state.
+ *
+ * Return 0 on success, or a negative error code if an I2C communication error
+ * occurred.
+ */
+static int
+as3645a_set_control(struct as3645a *flash, enum as_mode mode, bool on)
+{
+	u8 reg;
+
+	/* Configure output parameters and operation mode. */
+	reg = (flash->pdata->peak << AS_CONTROL_COIL_PEAK_SHIFT)
+	    | (on ? AS_CONTROL_OUT_ON : 0)
+	    | mode;
+
+	if (flash->led_mode == V4L2_FLASH_LED_MODE_FLASH &&
+	    flash->strobe_source == V4L2_FLASH_STROBE_SOURCE_EXTERNAL) {
+		reg |= AS_CONTROL_STROBE_TYPE_LEVEL
+		    |  AS_CONTROL_STROBE_ON;
+	}
+
+	return as3645a_write(flash, AS_CONTROL_REG, reg);
+}
+
+/*
+ * as3645a_set_output - Configure output and operation mode
+ * @flash: Flash controller
+ * @strobe: Strobe the flash (only valid in flash mode)
+ *
+ * Turn the LEDs output on/off and set the operation mode based on the current
+ * parameters.
+ *
+ * The AS3645A can't control the indicator LED independently of the flash/torch
+ * LED. If the flash controller is in V4L2_FLASH_LED_MODE_NONE mode, set the
+ * chip to indicator mode. Otherwise set it to assist light (torch) or flash
+ * mode.
+ *
+ * In indicator and assist modes, turn the output on/off based on the indicator
+ * and torch currents. In software strobe flash mode, turn the output on/off
+ * based on the strobe parameter.
+ */
+static int as3645a_set_output(struct as3645a *flash, bool strobe)
+{
+	enum as_mode mode;
+	bool on;
+
+	switch (flash->led_mode) {
+	case V4L2_FLASH_LED_MODE_NONE:
+		on = flash->indicator_current != 0;
+		mode = AS_MODE_INDICATOR;
+		break;
+	case V4L2_FLASH_LED_MODE_TORCH:
+		on = true;
+		mode = AS_MODE_ASSIST;
+		break;
+	case V4L2_FLASH_LED_MODE_FLASH:
+		on = strobe;
+		mode = AS_MODE_FLASH;
+		break;
+	default:
+		BUG();
+	}
+
+	/* Configure output parameters and operation mode. */
+	return as3645a_set_control(flash, mode, on);
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 controls
+ */
+
+static int as3645a_is_active(struct as3645a *flash)
+{
+	int ret;
+
+	ret = as3645a_read(flash, AS_CONTROL_REG);
+	return ret < 0 ? ret : !!(ret & AS_CONTROL_OUT_ON);
+}
+
+static int as3645a_read_fault(struct as3645a *flash)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
+	int rval;
+
+	/* NOTE: reading register clear fault status */
+	rval = as3645a_read(flash, AS_FAULT_INFO_REG);
+	if (rval < 0)
+		return rval;
+
+	if (rval & AS_FAULT_INFO_INDUCTOR_PEAK_LIMIT)
+		dev_dbg(&client->dev, "Inductor Peak limit fault\n");
+
+	if (rval & AS_FAULT_INFO_INDICATOR_LED)
+		dev_dbg(&client->dev, "Indicator LED fault: "
+			"Short circuit or open loop\n");
+
+	dev_dbg(&client->dev, "%u connected LEDs\n",
+		rval & AS_FAULT_INFO_LED_AMOUNT ? 2 : 1);
+
+	if (rval & AS_FAULT_INFO_TIMEOUT)
+		dev_dbg(&client->dev, "Timeout fault\n");
+
+	if (rval & AS_FAULT_INFO_OVER_TEMPERATURE)
+		dev_dbg(&client->dev, "Over temperature fault\n");
+
+	if (rval & AS_FAULT_INFO_SHORT_CIRCUIT)
+		dev_dbg(&client->dev, "Short circuit fault\n");
+
+	if (rval & AS_FAULT_INFO_OVER_VOLTAGE)
+		dev_dbg(&client->dev, "Over voltage fault: "
+			"Indicates missing capacitor or open connection\n");
+
+	return rval;
+}
+
+static int as3645a_get_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct as3645a *flash =
+		container_of(ctrl->handler, struct as3645a, ctrls);
+	struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
+	int value;
+
+	switch (ctrl->id) {
+	case V4L2_CID_FLASH_FAULT:
+		value = as3645a_read_fault(flash);
+		if (value < 0)
+			return value;
+
+		ctrl->cur.val = 0;
+		if (value & AS_FAULT_INFO_SHORT_CIRCUIT)
+			ctrl->cur.val |= V4L2_FLASH_FAULT_SHORT_CIRCUIT;
+		if (value & AS_FAULT_INFO_OVER_TEMPERATURE)
+			ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_TEMPERATURE;
+		if (value & AS_FAULT_INFO_TIMEOUT)
+			ctrl->cur.val |= V4L2_FLASH_FAULT_TIMEOUT;
+		if (value & AS_FAULT_INFO_OVER_VOLTAGE)
+			ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_VOLTAGE;
+		if (value & AS_FAULT_INFO_INDUCTOR_PEAK_LIMIT)
+			ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_CURRENT;
+		if (value & AS_FAULT_INFO_INDICATOR_LED)
+			ctrl->cur.val |= V4L2_FLASH_FAULT_INDICATOR;
+		break;
+
+	case V4L2_CID_FLASH_STROBE_STATUS:
+		if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) {
+			ctrl->cur.val = 0;
+			break;
+		}
+
+		value = as3645a_is_active(flash);
+		if (value < 0)
+			return value;
+
+		ctrl->cur.val = value;
+		break;
+	}
+
+	dev_dbg(&client->dev, "G_CTRL %08x:%d\n", ctrl->id, ctrl->cur.val);
+
+	return 0;
+}
+
+static int as3645a_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct as3645a *flash =
+		container_of(ctrl->handler, struct as3645a, ctrls);
+	struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
+	int ret;
+
+	dev_dbg(&client->dev, "S_CTRL %08x:%d\n", ctrl->id, ctrl->val);
+
+	/* If a control that doesn't apply to the current mode is modified,
+	 * we store the value and return immediately. The setting will be
+	 * applied when the LED mode is changed. Otherwise we apply the setting
+	 * immediately.
+	 */
+
+	switch (ctrl->id) {
+	case V4L2_CID_FLASH_LED_MODE:
+		if (flash->indicator_current)
+			return -EBUSY;
+
+		ret = as3645a_set_config(flash);
+		if (ret < 0)
+			return ret;
+
+		flash->led_mode = ctrl->val;
+		return as3645a_set_output(flash, false);
+
+	case V4L2_CID_FLASH_STROBE_SOURCE:
+		flash->strobe_source = ctrl->val;
+
+		/* Applies to flash mode only. */
+		if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
+			break;
+
+		return as3645a_set_output(flash, false);
+
+	case V4L2_CID_FLASH_STROBE:
+		if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
+			return -EBUSY;
+
+		return as3645a_set_output(flash, true);
+
+	case V4L2_CID_FLASH_STROBE_STOP:
+		if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
+			return -EBUSY;
+
+		return as3645a_set_output(flash, false);
+
+	case V4L2_CID_FLASH_TIMEOUT:
+		flash->timeout = ctrl->val;
+
+		/* Applies to flash mode only. */
+		if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
+			break;
+
+		return as3645a_set_config(flash);
+
+	case V4L2_CID_FLASH_INTENSITY:
+		flash->flash_current = (ctrl->val - AS3645A_FLASH_INTENSITY_MIN)
+				     / AS3645A_FLASH_INTENSITY_STEP;
+
+		/* Applies to flash mode only. */
+		if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
+			break;
+
+		return as3645a_set_config(flash);
+
+	case V4L2_CID_FLASH_TORCH_INTENSITY:
+		flash->assist_current =
+			(ctrl->val - AS3645A_TORCH_INTENSITY_MIN)
+			/ AS3645A_TORCH_INTENSITY_STEP;
+
+		/* Applies to torch mode only. */
+		if (flash->led_mode != V4L2_FLASH_LED_MODE_TORCH)
+			break;
+
+		return as3645a_set_config(flash);
+
+	case V4L2_CID_FLASH_INDICATOR_INTENSITY:
+		if (flash->led_mode != V4L2_FLASH_LED_MODE_NONE)
+			return -EBUSY;
+
+		flash->indicator_current =
+			(ctrl->val - AS3645A_INDICATOR_INTENSITY_MIN)
+			/ AS3645A_INDICATOR_INTENSITY_STEP;
+
+		ret = as3645a_set_config(flash);
+		if (ret < 0)
+			return ret;
+
+		if ((ctrl->val == 0) == (ctrl->cur.val == 0))
+			break;
+
+		return as3645a_set_output(flash, false);
+	}
+
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops as3645a_ctrl_ops = {
+	.g_volatile_ctrl = as3645a_get_ctrl,
+	.s_ctrl = as3645a_set_ctrl,
+};
+
+/* -----------------------------------------------------------------------------
+ * V4L2 subdev core operations
+ */
+
+/* Put device into know state. */
+static int as3645a_setup(struct as3645a *flash)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
+	int ret;
+
+	/* clear errors */
+	ret = as3645a_read(flash, AS_FAULT_INFO_REG);
+	if (ret < 0)
+		return ret;
+
+	dev_dbg(&client->dev, "Fault info: %02x\n", ret);
+
+	ret = as3645a_set_config(flash);
+	if (ret < 0)
+		return ret;
+
+	ret = as3645a_set_output(flash, false);
+	if (ret < 0)
+		return ret;
+
+	/* read status */
+	ret = as3645a_read_fault(flash);
+	if (ret < 0)
+		return ret;
+
+	dev_dbg(&client->dev, "AS_INDICATOR_AND_TIMER_REG: %02x\n",
+		as3645a_read(flash, AS_INDICATOR_AND_TIMER_REG));
+	dev_dbg(&client->dev, "AS_CURRENT_SET_REG: %02x\n",
+		as3645a_read(flash, AS_CURRENT_SET_REG));
+	dev_dbg(&client->dev, "AS_CONTROL_REG: %02x\n",
+		as3645a_read(flash, AS_CONTROL_REG));
+
+	return ret & ~AS_FAULT_INFO_LED_AMOUNT ? -EIO : 0;
+}
+
+static int __as3645a_set_power(struct as3645a *flash, int on)
+{
+	int ret;
+
+	if (!on)
+		as3645a_set_control(flash, AS_MODE_EXT_TORCH, false);
+
+	if (flash->pdata->set_power) {
+		ret = flash->pdata->set_power(&flash->subdev, on);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (!on)
+		return 0;
+
+	ret = as3645a_setup(flash);
+	if (ret < 0) {
+		if (flash->pdata->set_power)
+			flash->pdata->set_power(&flash->subdev, 0);
+	}
+
+	return ret;
+}
+
+static int as3645a_set_power(struct v4l2_subdev *sd, int on)
+{
+	struct as3645a *flash = to_as3645a(sd);
+	int ret = 0;
+
+	mutex_lock(&flash->power_lock);
+
+	if (flash->power_count == !on) {
+		ret = __as3645a_set_power(flash, !!on);
+		if (ret < 0)
+			goto done;
+	}
+
+	flash->power_count += on ? 1 : -1;
+	WARN_ON(flash->power_count < 0);
+
+done:
+	mutex_unlock(&flash->power_lock);
+	return ret;
+}
+
+static int as3645a_registered(struct v4l2_subdev *sd)
+{
+	struct as3645a *flash = to_as3645a(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int rval, man, model, rfu, version;
+	const char *vendor;
+
+	/* Power up the flash driver and read manufacturer ID, model ID, RFU
+	 * and version.
+	 */
+	rval = as3645a_set_power(&flash->subdev, 1);
+	if (rval < 0)
+		return rval;
+
+	rval = as3645a_read(flash, AS_DESIGN_INFO_REG);
+	if (rval < 0)
+		goto power_off;
+
+	man = AS_DESIGN_INFO_FACTORY(rval);
+	model = AS_DESIGN_INFO_MODEL(rval);
+
+	rval = as3645a_read(flash, AS_VERSION_CONTROL_REG);
+	if (rval < 0)
+		goto power_off;
+
+	rfu = AS_VERSION_CONTROL_RFU(rval);
+	version = AS_VERSION_CONTROL_VERSION(rval);
+
+	/* Verify the chip model and version. */
+	if (model != 0x01 || rfu != 0x00) {
+		dev_err(&client->dev, "AS3645A not detected "
+			"(model %d rfu %d)\n", model, rfu);
+		rval = -ENODEV;
+		goto power_off;
+	}
+
+	switch (man) {
+	case 1:
+		vendor = "AMS, Austria Micro Systems";
+		break;
+	case 2:
+		vendor = "ADI, Analog Devices Inc.";
+		break;
+	case 3:
+		vendor = "NSC, National Semiconductor";
+		break;
+	case 4:
+		vendor = "NXP";
+		break;
+	case 5:
+		vendor = "TI, Texas Instrument";
+		break;
+	default:
+		vendor = "Unknown";
+	}
+
+	dev_info(&client->dev, "Chip vendor: %s (%d) Version: %d\n", vendor,
+		 man, version);
+
+	rval = as3645a_write(flash, AS_PASSWORD_REG, AS_PASSWORD_UNLOCK_VALUE);
+	if (rval < 0)
+		goto power_off;
+
+	rval = as3645a_write(flash, AS_BOOST_REG, AS_BOOST_CURRENT_DISABLE);
+	if (rval < 0)
+		goto power_off;
+
+	/* Setup default values. This makes sure that the chip is in a known
+	 * state, in case the power rail can't be controlled.
+	 */
+	rval = as3645a_setup(flash);
+
+power_off:
+	as3645a_set_power(&flash->subdev, 0);
+
+	return rval;
+}
+
+static int as3645a_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	return as3645a_set_power(sd, 1);
+}
+
+static int as3645a_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	return as3645a_set_power(sd, 0);
+}
+
+static const struct v4l2_subdev_core_ops as3645a_core_ops = {
+	.s_power		= as3645a_set_power,
+};
+
+static const struct v4l2_subdev_ops as3645a_ops = {
+	.core = &as3645a_core_ops,
+};
+
+static const struct v4l2_subdev_internal_ops as3645a_internal_ops = {
+	.registered = as3645a_registered,
+	.open = as3645a_open,
+	.close = as3645a_close,
+};
+
+/* -----------------------------------------------------------------------------
+ *  I2C driver
+ */
+#ifdef CONFIG_PM
+
+static int as3645a_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+	struct as3645a *flash = to_as3645a(subdev);
+	int rval;
+
+	if (flash->power_count == 0)
+		return 0;
+
+	rval = __as3645a_set_power(flash, 0);
+
+	dev_dbg(&client->dev, "Suspend %s\n", rval < 0 ? "failed" : "ok");
+
+	return rval;
+}
+
+static int as3645a_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+	struct as3645a *flash = to_as3645a(subdev);
+	int rval;
+
+	if (flash->power_count == 0)
+		return 0;
+
+	rval = __as3645a_set_power(flash, 1);
+
+	dev_dbg(&client->dev, "Resume %s\n", rval < 0 ? "fail" : "ok");
+
+	return rval;
+}
+
+#else
+
+#define as3645a_suspend	NULL
+#define as3645a_resume	NULL
+
+#endif /* CONFIG_PM */
+
+/*
+ * as3645a_init_controls - Create controls
+ * @flash: The flash
+ *
+ * The number of LEDs reported in platform data is used to compute default
+ * limits. Parameters passed through platform data can override those limits.
+ */
+static int as3645a_init_controls(struct as3645a *flash)
+{
+	const struct as3645a_platform_data *pdata = flash->pdata;
+	struct v4l2_ctrl *ctrl;
+	int maximum;
+
+	v4l2_ctrl_handler_init(&flash->ctrls, 10);
+
+	/* V4L2_CID_FLASH_LED_MODE */
+	v4l2_ctrl_new_std_menu(&flash->ctrls, &as3645a_ctrl_ops,
+			       V4L2_CID_FLASH_LED_MODE, 2, ~7,
+			       V4L2_FLASH_LED_MODE_NONE);
+
+	/* V4L2_CID_FLASH_STROBE_SOURCE */
+	v4l2_ctrl_new_std_menu(&flash->ctrls, &as3645a_ctrl_ops,
+			       V4L2_CID_FLASH_STROBE_SOURCE,
+			       pdata->ext_strobe ? 1 : 0,
+			       pdata->ext_strobe ? ~3 : ~1,
+			       V4L2_FLASH_STROBE_SOURCE_SOFTWARE);
+
+	flash->strobe_source = V4L2_FLASH_STROBE_SOURCE_SOFTWARE;
+
+	/* V4L2_CID_FLASH_STROBE */
+	v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
+			  V4L2_CID_FLASH_STROBE, 0, 0, 0, 0);
+
+	/* V4L2_CID_FLASH_STROBE_STOP */
+	v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
+			  V4L2_CID_FLASH_STROBE_STOP, 0, 0, 0, 0);
+
+	/* V4L2_CID_FLASH_STROBE_STATUS */
+	ctrl = v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
+				 V4L2_CID_FLASH_STROBE_STATUS, 0, 1, 1, 1);
+	if (ctrl != NULL)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+	/* V4L2_CID_FLASH_TIMEOUT */
+	maximum = pdata->timeout_max;
+
+	v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
+			  V4L2_CID_FLASH_TIMEOUT, AS3645A_FLASH_TIMEOUT_MIN,
+			  maximum, AS3645A_FLASH_TIMEOUT_STEP, maximum);
+
+	flash->timeout = maximum;
+
+	/* V4L2_CID_FLASH_INTENSITY */
+	maximum = pdata->flash_max_current;
+
+	v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
+			  V4L2_CID_FLASH_INTENSITY, AS3645A_FLASH_INTENSITY_MIN,
+			  maximum, AS3645A_FLASH_INTENSITY_STEP, maximum);
+
+	flash->flash_current = (maximum - AS3645A_FLASH_INTENSITY_MIN)
+			     / AS3645A_FLASH_INTENSITY_STEP;
+
+	/* V4L2_CID_FLASH_TORCH_INTENSITY */
+	maximum = pdata->torch_max_current;
+
+	v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
+			  V4L2_CID_FLASH_TORCH_INTENSITY,
+			  AS3645A_TORCH_INTENSITY_MIN, maximum,
+			  AS3645A_TORCH_INTENSITY_STEP,
+			  AS3645A_TORCH_INTENSITY_MIN);
+
+	flash->assist_current = 0;
+
+	/* V4L2_CID_FLASH_INDICATOR_INTENSITY */
+	v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
+			  V4L2_CID_FLASH_INDICATOR_INTENSITY,
+			  AS3645A_INDICATOR_INTENSITY_MIN,
+			  AS3645A_INDICATOR_INTENSITY_MAX,
+			  AS3645A_INDICATOR_INTENSITY_STEP,
+			  AS3645A_INDICATOR_INTENSITY_MIN);
+
+	flash->indicator_current = 0;
+
+	/* V4L2_CID_FLASH_FAULT */
+	ctrl = v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
+				 V4L2_CID_FLASH_FAULT, 0,
+				 V4L2_FLASH_FAULT_OVER_VOLTAGE |
+				 V4L2_FLASH_FAULT_TIMEOUT |
+				 V4L2_FLASH_FAULT_OVER_TEMPERATURE |
+				 V4L2_FLASH_FAULT_SHORT_CIRCUIT, 0, 0);
+	if (ctrl != NULL)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+	flash->subdev.ctrl_handler = &flash->ctrls;
+
+	return flash->ctrls.error;
+}
+
+static int as3645a_probe(struct i2c_client *client,
+			 const struct i2c_device_id *devid)
+{
+	struct as3645a *flash;
+	int ret;
+
+	if (client->dev.platform_data == NULL)
+		return -ENODEV;
+
+	flash = kzalloc(sizeof(*flash), GFP_KERNEL);
+	if (flash == NULL)
+		return -ENOMEM;
+
+	flash->pdata = client->dev.platform_data;
+
+	v4l2_i2c_subdev_init(&flash->subdev, client, &as3645a_ops);
+	flash->subdev.internal_ops = &as3645a_internal_ops;
+	flash->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+
+	ret = as3645a_init_controls(flash);
+	if (ret < 0)
+		goto done;
+
+	ret = media_entity_init(&flash->subdev.entity, 0, NULL, 0);
+	if (ret < 0)
+		goto done;
+
+	flash->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
+
+	mutex_init(&flash->power_lock);
+
+	flash->led_mode = V4L2_FLASH_LED_MODE_NONE;
+
+done:
+	if (ret < 0) {
+		v4l2_ctrl_handler_free(&flash->ctrls);
+		kfree(flash);
+	}
+
+	return ret;
+}
+
+static int __exit as3645a_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+	struct as3645a *flash = to_as3645a(subdev);
+
+	v4l2_device_unregister_subdev(subdev);
+	v4l2_ctrl_handler_free(&flash->ctrls);
+	media_entity_cleanup(&flash->subdev.entity);
+	mutex_destroy(&flash->power_lock);
+	kfree(flash);
+
+	return 0;
+}
+
+static const struct i2c_device_id as3645a_id_table[] = {
+	{ AS3645A_NAME, 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, as3645a_id_table);
+
+static const struct dev_pm_ops as3645a_pm_ops = {
+	.suspend = as3645a_suspend,
+	.resume = as3645a_resume,
+};
+
+static struct i2c_driver as3645a_i2c_driver = {
+	.driver	= {
+		.name = AS3645A_NAME,
+		.pm   = &as3645a_pm_ops,
+	},
+	.probe	= as3645a_probe,
+	.remove	= __exit_p(as3645a_remove),
+	.id_table = as3645a_id_table,
+};
+
+static int __init as3645a_init(void)
+{
+	int rval;
+
+	rval = i2c_add_driver(&as3645a_i2c_driver);
+	if (rval)
+		pr_err("%s: Failed to register the driver\n", AS3645A_NAME);
+
+	return rval;
+}
+
+static void __exit as3645a_exit(void)
+{
+	i2c_del_driver(&as3645a_i2c_driver);
+}
+
+module_init(as3645a_init);
+module_exit(as3645a_exit);
+
+MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+MODULE_DESCRIPTION("LED flash driver for AS3645A, LM3555 and their clones");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/atmel-isi.c b/drivers/media/video/atmel-isi.c
index 8c775c5..fbc904f 100644
--- a/drivers/media/video/atmel-isi.c
+++ b/drivers/media/video/atmel-isi.c
@@ -1036,7 +1036,7 @@
 err_alloc_descriptors:
 	kfree(isi);
 err_alloc_isi:
-	clk_put(isi->pclk);
+	clk_put(pclk);
 
 	return ret;
 }
diff --git a/drivers/media/video/au0828/au0828-i2c.c b/drivers/media/video/au0828/au0828-i2c.c
index cbdb65c..05c299f 100644
--- a/drivers/media/video/au0828/au0828-i2c.c
+++ b/drivers/media/video/au0828/au0828-i2c.c
@@ -348,7 +348,7 @@
 	}
 }
 
-/* init + register i2c algo-bit adapter */
+/* init + register i2c adapter */
 int au0828_i2c_register(struct au0828_dev *dev)
 {
 	dprintk(1, "%s()\n", __func__);
diff --git a/drivers/media/video/bt8xx/bt848.h b/drivers/media/video/bt8xx/bt848.h
index 0bcd953..c37e6ac 100644
--- a/drivers/media/video/bt8xx/bt848.h
+++ b/drivers/media/video/bt8xx/bt848.h
@@ -30,6 +30,10 @@
 #ifndef PCI_DEVICE_ID_BT849
 #define PCI_DEVICE_ID_BT849     0x351
 #endif
+#ifndef PCI_DEVICE_ID_FUSION879
+#define PCI_DEVICE_ID_FUSION879	0x36c
+#endif
+
 #ifndef PCI_DEVICE_ID_BT878
 #define PCI_DEVICE_ID_BT878     0x36e
 #endif
@@ -37,7 +41,6 @@
 #define PCI_DEVICE_ID_BT879     0x36f
 #endif
 
-
 /* Brooktree 848 registers */
 
 #define BT848_DSTATUS          0x000
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index 5939021..ff2933a 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -80,6 +80,8 @@
 static void gv800s_muxsel(struct bttv *btv, unsigned int input);
 static void gv800s_init(struct bttv *btv);
 
+static void td3116_muxsel(struct bttv *btv, unsigned int input);
+
 static int terratec_active_radio_upgrade(struct bttv *btv);
 static int tea5757_read(struct bttv *btv);
 static int tea5757_write(struct bttv *btv, int value);
@@ -284,7 +286,8 @@
 	{ 0x10b42636, BTTV_BOARD_HAUPPAUGE878,  "STB ???" },
 	{ 0x217d6606, BTTV_BOARD_WINFAST2000,   "Leadtek WinFast TV 2000" },
 	{ 0xfff6f6ff, BTTV_BOARD_WINFAST2000,   "Leadtek WinFast TV 2000" },
-	{ 0x03116000, BTTV_BOARD_SENSORAY311,   "Sensoray 311" },
+	{ 0x03116000, BTTV_BOARD_SENSORAY311_611, "Sensoray 311" },
+	{ 0x06116000, BTTV_BOARD_SENSORAY311_611, "Sensoray 611" },
 	{ 0x00790e11, BTTV_BOARD_WINDVR,        "Canopus WinDVR PCI" },
 	{ 0xa0fca1a0, BTTV_BOARD_ZOLTRIX,       "Face to Face Tvmax" },
 	{ 0x82b2aa6a, BTTV_BOARD_SIMUS_GVC1100, "SIMUS GVC1100" },
@@ -341,6 +344,7 @@
 	{ 0x15401835, BTTV_BOARD_PV183,         "Provideo PV183-6" },
 	{ 0x15401836, BTTV_BOARD_PV183,         "Provideo PV183-7" },
 	{ 0x15401837, BTTV_BOARD_PV183,         "Provideo PV183-8" },
+	{ 0x3116f200, BTTV_BOARD_TVT_TD3116,	"Tongwei Video Technology TD-3116" },
 
 	{ 0, -1, NULL }
 };
@@ -1526,10 +1530,10 @@
 			GPIO20,22,23: R30,R29,R28
 		*/
 	},
-	[BTTV_BOARD_SENSORAY311] = {
+	[BTTV_BOARD_SENSORAY311_611] = {
 		/* Clay Kunz <ckunz@mail.arc.nasa.gov> */
-		/* you must jumper JP5 for the card to work */
-		.name           = "Sensoray 311",
+		/* you must jumper JP5 for the 311 card (PC/104+) to work */
+		.name           = "Sensoray 311/611",
 		.video_inputs   = 5,
 		/* .audio_inputs= 0, */
 		.svhs           = 4,
@@ -2879,6 +2883,16 @@
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 	},
+	[BTTV_BOARD_TVT_TD3116] = {
+		.name           = "Tongwei Video Technology TD-3116",
+		.video_inputs   = 16,
+		.gpiomask       = 0xc00ff,
+		.muxsel         = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2),
+		.muxsel_hook    = td3116_muxsel,
+		.svhs           = NO_SVHS,
+		.pll		= PLL_28,
+		.tuner_type     = TUNER_ABSENT,
+	},
 };
 
 static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -3228,6 +3242,42 @@
 	gpio_bits(0xf, inmux);
 }
 
+/*
+ * The TD3116 has 2 74HC4051 muxes wired to the MUX0 input of a bt878.
+ * The first 74HC4051 has the lower 8 inputs, the second one the higher 8.
+ * The muxes are controlled via a 74HC373 latch which is connected to
+ * GPIOs 0-7. GPIO 18 is connected to the LE signal of the latch.
+ * Q0 of the latch is connected to the Enable (~E) input of the first
+ * 74HC4051. Q1 - Q3 are connected to S0 - S2 of the same 74HC4051.
+ * Q4 - Q7 are connected to the second 74HC4051 in the same way.
+ */
+
+static void td3116_latch_value(struct bttv *btv, u32 value)
+{
+	gpio_bits((1<<18) | 0xff, value);
+	gpio_bits((1<<18) | 0xff, (1<<18) | value);
+	udelay(1);
+	gpio_bits((1<<18) | 0xff, value);
+}
+
+static void td3116_muxsel(struct bttv *btv, unsigned int input)
+{
+	u32 value;
+	u32 highbit;
+
+	highbit = (input & 0x8) >> 3 ;
+
+	/* Disable outputs and set value in the mux */
+	value = 0x11; /* Disable outputs */
+	value |= ((input & 0x7) << 1)  << (4 * highbit);
+	td3116_latch_value(btv, value);
+
+	/* Enable the correct output */
+	value &= ~0x11;
+	value |= ((highbit ^ 0x1) << 4) | highbit;
+	td3116_latch_value(btv, value);
+}
+
 /* ----------------------------------------------------------------------- */
 
 static void bttv_reset_audio(struct bttv *btv)
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 3dd0660..76c301f 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -4572,6 +4572,7 @@
 	{PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT849), 0},
 	{PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT878), 0},
 	{PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT879), 0},
+	{PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_FUSION879), 0},
 	{0,}
 };
 
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c
index e3952af..580c8e6 100644
--- a/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/drivers/media/video/bt8xx/bttv-i2c.c
@@ -346,7 +346,7 @@
 	}
 }
 
-/* init + register i2c algo-bit adapter */
+/* init + register i2c adapter */
 int __devinit init_bttv_i2c(struct bttv *btv)
 {
 	strlcpy(btv->i2c_client.name, "bttv internal", I2C_NAME_SIZE);
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h
index c633359..c517161 100644
--- a/drivers/media/video/bt8xx/bttv.h
+++ b/drivers/media/video/bt8xx/bttv.h
@@ -96,7 +96,7 @@
 #define BTTV_BOARD_PV_BT878P_PLUS          0x46
 #define BTTV_BOARD_FLYVIDEO98EZ            0x47
 #define BTTV_BOARD_PV_BT878P_9B            0x48
-#define BTTV_BOARD_SENSORAY311             0x49
+#define BTTV_BOARD_SENSORAY311_611         0x49
 #define BTTV_BOARD_RV605                   0x4a
 #define BTTV_BOARD_POWERCLR_MTV878         0x4b
 #define BTTV_BOARD_WINDVR                  0x4c
@@ -183,6 +183,7 @@
 #define BTTV_BOARD_GEOVISION_GV800S	   0x9d
 #define BTTV_BOARD_GEOVISION_GV800S_SL	   0x9e
 #define BTTV_BOARD_PV183                   0x9f
+#define BTTV_BOARD_TVT_TD3116		   0xa0
 
 
 /* more card-specific defines */
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index 040aaa8..51609d5 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -232,7 +232,7 @@
 	.timeout	= CX18_ALGO_BIT_TIMEOUT*HZ /* jiffies */
 };
 
-/* init + register i2c algo-bit adapter */
+/* init + register i2c adapter */
 int init_cx18_i2c(struct cx18 *cx)
 {
 	int i, err;
diff --git a/drivers/media/video/cx18/cx18-i2c.h b/drivers/media/video/cx18/cx18-i2c.h
index bdfd192..1180fdc 100644
--- a/drivers/media/video/cx18/cx18-i2c.h
+++ b/drivers/media/video/cx18/cx18-i2c.h
@@ -24,6 +24,6 @@
 int cx18_i2c_register(struct cx18 *cx, unsigned idx);
 struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw);
 
-/* init + register i2c algo-bit adapter */
+/* init + register i2c adapter */
 int init_cx18_i2c(struct cx18 *cx);
 void exit_cx18_i2c(struct cx18 *cx);
diff --git a/drivers/media/video/cx231xx/Kconfig b/drivers/media/video/cx231xx/Kconfig
index ae85a7a..c74ce9e 100644
--- a/drivers/media/video/cx231xx/Kconfig
+++ b/drivers/media/video/cx231xx/Kconfig
@@ -42,8 +42,8 @@
 	tristate "DVB/ATSC Support for Cx231xx based TV cards"
 	depends on VIDEO_CX231XX && DVB_CORE
 	select VIDEOBUF_DVB
-	select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMISE
-	select MEDIA_TUNER_NXP18271 if !DVB_FE_CUSTOMISE
+	select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
 	select DVB_MB86A20S if !DVB_FE_CUSTOMISE
 
 	---help---
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index c3cf089..ac03c26 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -438,6 +438,36 @@
 			.gpio0  = 0,
 		} },
 	},
+	[CX23885_BOARD_MYGICA_X8507] = {
+		.name		= "Mygica X8507",
+		.tuner_type = TUNER_XC5000,
+		.tuner_addr = 0x61,
+		.tuner_bus	= 1,
+		.porta		= CX23885_ANALOG_VIDEO,
+		.input		= {
+			{
+				.type   = CX23885_VMUX_TELEVISION,
+				.vmux   = CX25840_COMPOSITE2,
+				.amux   = CX25840_AUDIO8,
+			},
+			{
+				.type   = CX23885_VMUX_COMPOSITE1,
+				.vmux   = CX25840_COMPOSITE8,
+			},
+			{
+				.type   = CX23885_VMUX_SVIDEO,
+				.vmux   = CX25840_SVIDEO_LUMA3 |
+						CX25840_SVIDEO_CHROMA4,
+			},
+			{
+				.type   = CX23885_VMUX_COMPONENT,
+				.vmux   = CX25840_COMPONENT_ON |
+					CX25840_VIN1_CH1 |
+					CX25840_VIN6_CH2 |
+					CX25840_VIN7_CH3,
+			},
+		},
+	}
 };
 const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
 
@@ -637,6 +667,10 @@
 		.subvendor = 0x1b55,
 		.subdevice = 0xe2e4,
 		.card      = CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF,
+	}, {
+		.subvendor = 0x14f1,
+		.subdevice = 0x8502,
+		.card      = CX23885_BOARD_MYGICA_X8507,
 	},
 };
 const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -1068,6 +1102,7 @@
 		break;
 	case CX23885_BOARD_MYGICA_X8506:
 	case CX23885_BOARD_MAGICPRO_PROHDTVE2:
+	case CX23885_BOARD_MYGICA_X8507:
 		/* GPIO-0 (0)Analog / (1)Digital TV */
 		/* GPIO-1 reset XC5000 */
 		/* GPIO-2 reset LGS8GL5 / LGS8G75 */
@@ -1468,6 +1503,7 @@
 	case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID:
 	case CX23885_BOARD_HAUPPAUGE_HVR1500:
 	case CX23885_BOARD_MPX885:
+	case CX23885_BOARD_MYGICA_X8507:
 		dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
 				&dev->i2c_bus[2].i2c_adap,
 				"cx25840", 0x88 >> 1, NULL);
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
index 0ff7a9e..be1e21d 100644
--- a/drivers/media/video/cx23885/cx23885-i2c.c
+++ b/drivers/media/video/cx23885/cx23885-i2c.c
@@ -309,7 +309,7 @@
 	}
 }
 
-/* init + register i2c algo-bit adapter */
+/* init + register i2c adapter */
 int cx23885_i2c_register(struct cx23885_i2c *bus)
 {
 	struct cx23885_dev *dev = bus->dev;
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index e730b92..7415524 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -492,7 +492,8 @@
 	dev->input = input;
 
 	if (dev->board == CX23885_BOARD_MYGICA_X8506 ||
-		dev->board == CX23885_BOARD_MAGICPRO_PROHDTVE2) {
+		dev->board == CX23885_BOARD_MAGICPRO_PROHDTVE2 ||
+		dev->board == CX23885_BOARD_MYGICA_X8507) {
 		/* Select Analog TV */
 		if (INPUT(input)->type == CX23885_VMUX_TELEVISION)
 			cx23885_gpio_clear(dev, GPIO_0);
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index b49036f..519f40d 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -87,6 +87,7 @@
 #define CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF 30
 #define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000 31
 #define CX23885_BOARD_MPX885                   32
+#define CX23885_BOARD_MYGICA_X8507             33
 
 #define GPIO_0 0x00000001
 #define GPIO_1 0x00000002
diff --git a/drivers/media/video/cx25821/cx25821-alsa.c b/drivers/media/video/cx25821/cx25821-alsa.c
index 09e99de..6142ae2 100644
--- a/drivers/media/video/cx25821/cx25821-alsa.c
+++ b/drivers/media/video/cx25821/cx25821-alsa.c
@@ -176,8 +176,7 @@
 
 	/* Set the input mode to 16-bit */
 	tmp = cx_read(AUD_A_CFG);
-	cx_write(AUD_A_CFG,
-		 tmp | FLD_AUD_DST_PK_MODE | FLD_AUD_DST_ENABLE |
+	cx_write(AUD_A_CFG, tmp | FLD_AUD_DST_PK_MODE | FLD_AUD_DST_ENABLE |
 		 FLD_AUD_CLK_ENABLE);
 
 	/*
@@ -188,9 +187,8 @@
 	*/
 
 	/* Enables corresponding bits at AUD_INT_STAT */
-	cx_write(AUD_A_INT_MSK,
-		 FLD_AUD_DST_RISCI1 | FLD_AUD_DST_OF | FLD_AUD_DST_SYNC |
-		 FLD_AUD_DST_OPC_ERR);
+	cx_write(AUD_A_INT_MSK, FLD_AUD_DST_RISCI1 | FLD_AUD_DST_OF |
+		 FLD_AUD_DST_SYNC | FLD_AUD_DST_OPC_ERR);
 
 	/* Clean any pending interrupt bits already set */
 	cx_write(AUD_A_INT_STAT, ~0);
@@ -200,8 +198,8 @@
 
 	/* Turn on audio downstream fifo and risc enable 0x101 */
 	tmp = cx_read(AUD_INT_DMA_CTL);
-	cx_set(AUD_INT_DMA_CTL,
-	       tmp | (FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN));
+	cx_set(AUD_INT_DMA_CTL, tmp |
+	       (FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN));
 
 	mdelay(100);
 	return 0;
@@ -220,9 +218,8 @@
 
 	/* disable irqs */
 	cx_clear(PCI_INT_MSK, PCI_MSK_AUD_INT);
-	cx_clear(AUD_A_INT_MSK,
-		 AUD_INT_OPC_ERR | AUD_INT_DN_SYNC | AUD_INT_DN_RISCI2 |
-		 AUD_INT_DN_RISCI1);
+	cx_clear(AUD_A_INT_MSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC |
+		 AUD_INT_DN_RISCI2 | AUD_INT_DN_RISCI1);
 
 	return 0;
 }
@@ -234,15 +231,15 @@
  */
 static char *cx25821_aud_irqs[32] = {
 	"dn_risci1", "up_risci1", "rds_dn_risc1",	/* 0-2 */
-	NULL,			/* reserved */
+	NULL,						/* reserved */
 	"dn_risci2", "up_risci2", "rds_dn_risc2",	/* 4-6 */
-	NULL,			/* reserved */
-	"dnf_of", "upf_uf", "rds_dnf_uf",	/* 8-10 */
-	NULL,			/* reserved */
-	"dn_sync", "up_sync", "rds_dn_sync",	/* 12-14 */
-	NULL,			/* reserved */
-	"opc_err", "par_err", "rip_err",	/* 16-18 */
-	"pci_abort", "ber_irq", "mchg_irq"	/* 19-21 */
+	NULL,						/* reserved */
+	"dnf_of", "upf_uf", "rds_dnf_uf",		/* 8-10 */
+	NULL,						/* reserved */
+	"dn_sync", "up_sync", "rds_dn_sync",		/* 12-14 */
+	NULL,						/* reserved */
+	"opc_err", "par_err", "rip_err",		/* 16-18 */
+	"pci_abort", "ber_irq", "mchg_irq"		/* 19-21 */
 };
 
 /*
@@ -258,10 +255,8 @@
 
 	cx_write(AUD_A_INT_STAT, status);
 	if (debug > 1 || (status & mask & ~0xff))
-		cx25821_print_irqbits(dev->name, "irq aud",
-				      cx25821_aud_irqs,
-				      ARRAY_SIZE(cx25821_aud_irqs), status,
-				      mask);
+		cx25821_print_irqbits(dev->name, "irq aud", cx25821_aud_irqs,
+				ARRAY_SIZE(cx25821_aud_irqs), status, mask);
 
 	/* risc op code error */
 	if (status & AUD_INT_OPC_ERR) {
@@ -270,8 +265,7 @@
 		cx_clear(AUD_INT_DMA_CTL,
 			 FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN);
 		cx25821_sram_channel_dump_audio(dev,
-						&cx25821_sram_channels
-						[AUDIO_SRAM_CHANNEL]);
+				&cx25821_sram_channels[AUDIO_SRAM_CHANNEL]);
 	}
 	if (status & AUD_INT_DN_SYNC) {
 		pr_warn("WARNING %s: Downstream sync error!\n", dev->name);
@@ -317,8 +311,9 @@
 				cx25821_aud_irq(chip, audint_status,
 						audint_mask);
 				break;
-			} else
+			} else {
 				goto out;
+			}
 		}
 
 		handled = 1;
@@ -361,9 +356,8 @@
  */
 #define DEFAULT_FIFO_SIZE	384
 static struct snd_pcm_hardware snd_cx25821_digital_hw = {
-	.info = SNDRV_PCM_INFO_MMAP |
-	    SNDRV_PCM_INFO_INTERLEAVED |
-	    SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID,
+	.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID,
 	.formats = SNDRV_PCM_FMTBIT_S16_LE,
 
 	.rates = SNDRV_PCM_RATE_48000,
@@ -396,8 +390,8 @@
 		return -ENODEV;
 	}
 
-	err =
-	    snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS);
+	err = snd_pcm_hw_constraint_pow2(runtime, 0,
+					 SNDRV_PCM_HW_PARAM_PERIODS);
 	if (err < 0)
 		goto _error;
 
@@ -468,8 +462,7 @@
 	dma = &buf->dma;
 	videobuf_dma_init(dma);
 	ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE,
-				       (PAGE_ALIGN(chip->dma_size) >>
-					PAGE_SHIFT));
+			(PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT));
 	if (ret < 0)
 		goto error;
 
@@ -477,10 +470,8 @@
 	if (ret < 0)
 		goto error;
 
-	ret =
-	    cx25821_risc_databuffer_audio(chip->pci, &buf->risc, dma->sglist,
-					  chip->period_size, chip->num_periods,
-					  1);
+	ret = cx25821_risc_databuffer_audio(chip->pci, &buf->risc, dma->sglist,
+			chip->period_size, chip->num_periods, 1);
 	if (ret < 0) {
 		pr_info("DEBUG: ERROR after cx25821_risc_databuffer_audio()\n");
 		goto error;
@@ -686,7 +677,7 @@
 	}
 
 	err = snd_card_create(index[devno], id[devno], THIS_MODULE,
-			 sizeof(struct cx25821_audio_dev), &card);
+			sizeof(struct cx25821_audio_dev), &card);
 	if (err < 0) {
 		pr_info("DEBUG ERROR: cannot create snd_card_new in %s\n",
 			__func__);
@@ -711,8 +702,8 @@
 			  IRQF_SHARED, chip->dev->name, chip);
 
 	if (err < 0) {
-		pr_err("ERROR %s: can't get IRQ %d for ALSA\n",
-		       chip->dev->name, dev->pci->irq);
+		pr_err("ERROR %s: can't get IRQ %d for ALSA\n", chip->dev->name,
+			dev->pci->irq);
 		goto error;
 	}
 
@@ -730,8 +721,8 @@
 		chip->iobase, chip->irq);
 	strcpy(card->mixername, "CX25821");
 
-	pr_info("%s/%i: ALSA support for cx25821 boards\n",
-		card->driver, devno);
+	pr_info("%s/%i: ALSA support for cx25821 boards\n", card->driver,
+		devno);
 
 	err = snd_card_register(card);
 	if (err < 0) {
diff --git a/drivers/media/video/cx25821/cx25821-audio-upstream.c b/drivers/media/video/cx25821/cx25821-audio-upstream.c
index c20d6de..20c7ca3 100644
--- a/drivers/media/video/cx25821/cx25821-audio-upstream.c
+++ b/drivers/media/video/cx25821/cx25821-audio-upstream.c
@@ -107,7 +107,7 @@
 {
 	unsigned int line;
 	struct sram_channel *sram_ch =
-	   dev->channels[dev->_audio_upstream_channel].sram_channels;
+		dev->channels[dev->_audio_upstream_channel].sram_channels;
 	int offset = 0;
 
 	/* scan lines */
@@ -175,10 +175,8 @@
 		}
 
 		rp = cx25821_risc_field_upstream_audio(dev, rp,
-						       dev->
-						       _audiodata_buf_phys_addr
-						       + databuf_offset, bpl,
-						       fifo_enable);
+				dev->_audiodata_buf_phys_addr + databuf_offset,
+				bpl, fifo_enable);
 
 		if (USE_RISC_NOOP_AUDIO) {
 			for (i = 0; i < NUM_NO_OPS; i++)
@@ -193,7 +191,7 @@
 
 		/* Recalculate virtual address based on frame index */
 		rp = dev->_risc_virt_addr + RISC_SYNC_INSTRUCTION_SIZE / 4 +
-		    (AUDIO_RISC_DMA_BUF_SIZE * (frame + 1) / 4);
+			(AUDIO_RISC_DMA_BUF_SIZE * (frame + 1) / 4);
 	}
 
 	return 0;
@@ -218,7 +216,7 @@
 void cx25821_stop_upstream_audio(struct cx25821_dev *dev)
 {
 	struct sram_channel *sram_ch =
-	   dev->channels[AUDIO_UPSTREAM_SRAM_CHANNEL_B].sram_channels;
+		dev->channels[AUDIO_UPSTREAM_SRAM_CHANNEL_B].sram_channels;
 	u32 tmp = 0;
 
 	if (!dev->_audio_is_running) {
@@ -286,14 +284,14 @@
 	} else {
 		if (!(myfile->f_op)) {
 			pr_err("%s(): File has no file operations registered!\n",
-			       __func__);
+				__func__);
 			filp_close(myfile, NULL);
 			return -EIO;
 		}
 
 		if (!myfile->f_op->read) {
 			pr_err("%s(): File has no READ operations registered!\n",
-			       __func__);
+				__func__);
 			filp_close(myfile, NULL);
 			return -EIO;
 		}
@@ -305,14 +303,14 @@
 		for (i = 0; i < dev->_audio_lines_count; i++) {
 			pos = file_offset;
 
-			vfs_read_retval =
-			    vfs_read(myfile, mybuf, line_size, &pos);
+			vfs_read_retval = vfs_read(myfile, mybuf, line_size,
+									&pos);
 
 			if (vfs_read_retval > 0 && vfs_read_retval == line_size
 			    && dev->_audiodata_buf_virt_addr != NULL) {
 				memcpy((void *)(dev->_audiodata_buf_virt_addr +
 						frame_offset / 4), mybuf,
-				       vfs_read_retval);
+					vfs_read_retval);
 			}
 
 			file_offset += vfs_read_retval;
@@ -328,8 +326,8 @@
 		if (i > 0)
 			dev->_audioframe_count++;
 
-		dev->_audiofile_status =
-		    (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
+		dev->_audiofile_status = (vfs_read_retval == line_size) ?
+						IN_PROGRESS : END_OF_FILE;
 
 		set_fs(old_fs);
 		filp_close(myfile, NULL);
@@ -340,12 +338,12 @@
 
 static void cx25821_audioups_handler(struct work_struct *work)
 {
-	struct cx25821_dev *dev =
-	    container_of(work, struct cx25821_dev, _audio_work_entry);
+	struct cx25821_dev *dev = container_of(work, struct cx25821_dev,
+			_audio_work_entry);
 
 	if (!dev) {
 		pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n",
-		       __func__);
+			__func__);
 		return;
 	}
 
@@ -370,19 +368,19 @@
 	if (IS_ERR(myfile)) {
 		const int open_errno = -PTR_ERR(myfile);
 		pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
-		       __func__, dev->_audiofilename, open_errno);
+			__func__, dev->_audiofilename, open_errno);
 		return PTR_ERR(myfile);
 	} else {
 		if (!(myfile->f_op)) {
 			pr_err("%s(): File has no file operations registered!\n",
-			       __func__);
+				__func__);
 			filp_close(myfile, NULL);
 			return -EIO;
 		}
 
 		if (!myfile->f_op->read) {
 			pr_err("%s(): File has no READ operations registered!\n",
-			       __func__);
+				__func__);
 			filp_close(myfile, NULL);
 			return -EIO;
 		}
@@ -395,12 +393,12 @@
 			for (i = 0; i < dev->_audio_lines_count; i++) {
 				pos = offset;
 
-				vfs_read_retval =
-				    vfs_read(myfile, mybuf, line_size, &pos);
+				vfs_read_retval = vfs_read(myfile, mybuf,
+						line_size, &pos);
 
-				if (vfs_read_retval > 0
-				    && vfs_read_retval == line_size
-				    && dev->_audiodata_buf_virt_addr != NULL) {
+				if (vfs_read_retval > 0 &&
+				    vfs_read_retval == line_size &&
+				    dev->_audiodata_buf_virt_addr != NULL) {
 					memcpy((void *)(dev->
 							_audiodata_buf_virt_addr
 							+ offset / 4), mybuf,
@@ -423,8 +421,8 @@
 				break;
 		}
 
-		dev->_audiofile_status =
-		    (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
+		dev->_audiofile_status = (vfs_read_retval == line_size) ?
+						IN_PROGRESS : END_OF_FILE;
 
 		set_fs(old_fs);
 		myfile->f_pos = 0;
@@ -444,9 +442,8 @@
 
 	cx25821_free_memory_audio(dev);
 
-	dev->_risc_virt_addr =
-	    pci_alloc_consistent(dev->pci, dev->audio_upstream_riscbuf_size,
-				 &dma_addr);
+	dev->_risc_virt_addr = pci_alloc_consistent(dev->pci,
+			dev->audio_upstream_riscbuf_size, &dma_addr);
 	dev->_risc_virt_start_addr = dev->_risc_virt_addr;
 	dev->_risc_phys_start_addr = dma_addr;
 	dev->_risc_phys_addr = dma_addr;
@@ -454,22 +451,21 @@
 
 	if (!dev->_risc_virt_addr) {
 		printk(KERN_DEBUG
-		       pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for RISC program! Returning\n"));
+			pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for RISC program! Returning\n"));
 		return -ENOMEM;
 	}
 	/* Clear out memory at address */
 	memset(dev->_risc_virt_addr, 0, dev->_audiorisc_size);
 
 	/* For Audio Data buffer allocation */
-	dev->_audiodata_buf_virt_addr =
-	    pci_alloc_consistent(dev->pci, dev->audio_upstream_databuf_size,
-				 &data_dma_addr);
+	dev->_audiodata_buf_virt_addr = pci_alloc_consistent(dev->pci,
+			dev->audio_upstream_databuf_size, &data_dma_addr);
 	dev->_audiodata_buf_phys_addr = data_dma_addr;
 	dev->_audiodata_buf_size = dev->audio_upstream_databuf_size;
 
 	if (!dev->_audiodata_buf_virt_addr) {
 		printk(KERN_DEBUG
-		       pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for data buffer! Returning\n"));
+			pr_fmt("ERROR: pci_alloc_consistent() FAILED to allocate memory for data buffer! Returning\n"));
 		return -ENOMEM;
 	}
 	/* Clear out memory at address */
@@ -480,12 +476,11 @@
 		return ret;
 
 	/* Creating RISC programs */
-	ret =
-	    cx25821_risc_buffer_upstream_audio(dev, dev->pci, bpl,
-					       dev->_audio_lines_count);
+	ret = cx25821_risc_buffer_upstream_audio(dev, dev->pci, bpl,
+						dev->_audio_lines_count);
 	if (ret < 0) {
 		printk(KERN_DEBUG
-		       pr_fmt("ERROR creating audio upstream RISC programs!\n"));
+			pr_fmt("ERROR creating audio upstream RISC programs!\n"));
 		goto error;
 	}
 
@@ -533,9 +528,9 @@
 
 			if (dev->_risc_virt_start_addr != NULL) {
 				risc_phys_jump_addr =
-				    dev->_risc_phys_start_addr +
-				    RISC_SYNC_INSTRUCTION_SIZE +
-				    AUDIO_RISC_DMA_BUF_SIZE;
+					dev->_risc_phys_start_addr +
+					RISC_SYNC_INSTRUCTION_SIZE +
+					AUDIO_RISC_DMA_BUF_SIZE;
 
 				rp = cx25821_risc_field_upstream_audio(dev,
 						dev->_risc_virt_start_addr + 1,
@@ -632,7 +627,7 @@
 		/* 10 millisecond timeout */
 		if (count++ > 1000) {
 			pr_err("ERROR: %s() fifo is NOT turned on. Timeout!\n",
-			       __func__);
+				__func__);
 			return;
 		}
 
@@ -661,9 +656,9 @@
 
 	/* Set the input mode to 16-bit */
 	tmp = cx_read(sram_ch->aud_cfg);
-	tmp |=
-	    FLD_AUD_SRC_ENABLE | FLD_AUD_DST_PK_MODE | FLD_AUD_CLK_ENABLE |
-	    FLD_AUD_MASTER_MODE | FLD_AUD_CLK_SELECT_PLL_D | FLD_AUD_SONY_MODE;
+	tmp |= FLD_AUD_SRC_ENABLE | FLD_AUD_DST_PK_MODE | FLD_AUD_CLK_ENABLE |
+		FLD_AUD_MASTER_MODE | FLD_AUD_CLK_SELECT_PLL_D |
+		FLD_AUD_SONY_MODE;
 	cx_write(sram_ch->aud_cfg, tmp);
 
 	/* Read and write back the interrupt status register to clear it */
@@ -678,12 +673,11 @@
 	tmp = cx_read(sram_ch->int_msk);
 	cx_write(sram_ch->int_msk, tmp |= _intr_msk);
 
-	err =
-	    request_irq(dev->pci->irq, cx25821_upstream_irq_audio,
+	err = request_irq(dev->pci->irq, cx25821_upstream_irq_audio,
 			IRQF_SHARED, dev->name, dev);
 	if (err < 0) {
-		pr_err("%s: can't get upstream IRQ %d\n",
-		       dev->name, dev->pci->irq);
+		pr_err("%s: can't get upstream IRQ %d\n", dev->name,
+				dev->pci->irq);
 		goto fail_irq;
 	}
 
@@ -726,7 +720,7 @@
 
 	if (!dev->_irq_audio_queues) {
 		printk(KERN_DEBUG
-		       pr_fmt("ERROR: create_singlethread_workqueue() for Audio FAILED!\n"));
+			pr_fmt("ERROR: create_singlethread_workqueue() for Audio FAILED!\n"));
 		return -ENOMEM;
 	}
 
@@ -739,33 +733,30 @@
 
 	if (dev->input_audiofilename) {
 		str_length = strlen(dev->input_audiofilename);
-		dev->_audiofilename = kmalloc(str_length + 1, GFP_KERNEL);
+		dev->_audiofilename = kmemdup(dev->input_audiofilename,
+					      str_length + 1, GFP_KERNEL);
 
 		if (!dev->_audiofilename)
 			goto error;
 
-		memcpy(dev->_audiofilename, dev->input_audiofilename,
-		       str_length + 1);
-
 		/* Default if filename is empty string */
 		if (strcmp(dev->input_audiofilename, "") == 0)
 			dev->_audiofilename = "/root/audioGOOD.wav";
 	} else {
 		str_length = strlen(_defaultAudioName);
-		dev->_audiofilename = kmalloc(str_length + 1, GFP_KERNEL);
+		dev->_audiofilename = kmemdup(_defaultAudioName,
+					      str_length + 1, GFP_KERNEL);
 
 		if (!dev->_audiofilename)
 			goto error;
-
-		memcpy(dev->_audiofilename, _defaultAudioName, str_length + 1);
 	}
 
 	retval = cx25821_sram_channel_setup_upstream_audio(dev, sram_ch,
 							_line_size, 0);
 
 	dev->audio_upstream_riscbuf_size =
-	    AUDIO_RISC_DMA_BUF_SIZE * NUM_AUDIO_PROGS +
-	    RISC_SYNC_INSTRUCTION_SIZE;
+		AUDIO_RISC_DMA_BUF_SIZE * NUM_AUDIO_PROGS +
+		RISC_SYNC_INSTRUCTION_SIZE;
 	dev->audio_upstream_databuf_size = AUDIO_DATA_BUF_SZ * NUM_AUDIO_PROGS;
 
 	/* Allocating buffers and prepare RISC program */
@@ -773,7 +764,7 @@
 							_line_size);
 	if (retval < 0) {
 		pr_err("%s: Failed to set up Audio upstream buffers!\n",
-		       dev->name);
+			dev->name);
 		goto error;
 	}
 	/* Start RISC engine */
diff --git a/drivers/media/video/cx25821/cx25821-audio.h b/drivers/media/video/cx25821/cx25821-audio.h
index 8eb55b7..1fc2d24 100644
--- a/drivers/media/video/cx25821/cx25821-audio.h
+++ b/drivers/media/video/cx25821/cx25821-audio.h
@@ -23,39 +23,40 @@
 #ifndef __CX25821_AUDIO_H__
 #define __CX25821_AUDIO_H__
 
-#define USE_RISC_NOOP               1
-#define LINES_PER_BUFFER            15
-#define AUDIO_LINE_SIZE             128
+#define USE_RISC_NOOP		1
+#define LINES_PER_BUFFER	15
+#define AUDIO_LINE_SIZE		128
 
 /* Number of buffer programs to use at once. */
-#define NUMBER_OF_PROGRAMS  8
+#define NUMBER_OF_PROGRAMS	8
 
 /*
  * Max size of the RISC program for a buffer. - worst case is 2 writes per line
  * Space is also added for the 4 no-op instructions added on the end.
  */
 #ifndef USE_RISC_NOOP
-#define MAX_BUFFER_PROGRAM_SIZE     \
-	(2 * LINES_PER_BUFFER * RISC_WRITE_INSTRUCTION_SIZE + \
-	RISC_WRITECR_INSTRUCTION_SIZE * 4)
+#define MAX_BUFFER_PROGRAM_SIZE						\
+	(2 * LINES_PER_BUFFER * RISC_WRITE_INSTRUCTION_SIZE +		\
+	 RISC_WRITECR_INSTRUCTION_SIZE * 4)
 #endif
 
 /* MAE 12 July 2005 Try to use NOOP RISC instruction instead */
 #ifdef USE_RISC_NOOP
-#define MAX_BUFFER_PROGRAM_SIZE     \
-	(2 * LINES_PER_BUFFER * RISC_WRITE_INSTRUCTION_SIZE + \
-	RISC_NOOP_INSTRUCTION_SIZE * 4)
+#define MAX_BUFFER_PROGRAM_SIZE						\
+	(2 * LINES_PER_BUFFER * RISC_WRITE_INSTRUCTION_SIZE +		\
+	 RISC_NOOP_INSTRUCTION_SIZE * 4)
 #endif
 
 /* Sizes of various instructions in bytes.  Used when adding instructions. */
-#define RISC_WRITE_INSTRUCTION_SIZE 12
-#define RISC_JUMP_INSTRUCTION_SIZE  12
-#define RISC_SKIP_INSTRUCTION_SIZE  4
-#define RISC_SYNC_INSTRUCTION_SIZE  4
-#define RISC_WRITECR_INSTRUCTION_SIZE  16
-#define RISC_NOOP_INSTRUCTION_SIZE 4
+#define RISC_WRITE_INSTRUCTION_SIZE	12
+#define RISC_JUMP_INSTRUCTION_SIZE	12
+#define RISC_SKIP_INSTRUCTION_SIZE	4
+#define RISC_SYNC_INSTRUCTION_SIZE	4
+#define RISC_WRITECR_INSTRUCTION_SIZE	16
+#define RISC_NOOP_INSTRUCTION_SIZE	4
 
-#define MAX_AUDIO_DMA_BUFFER_SIZE	\
-(MAX_BUFFER_PROGRAM_SIZE * NUMBER_OF_PROGRAMS + RISC_SYNC_INSTRUCTION_SIZE)
+#define MAX_AUDIO_DMA_BUFFER_SIZE					\
+	(MAX_BUFFER_PROGRAM_SIZE * NUMBER_OF_PROGRAMS +			\
+	 RISC_SYNC_INSTRUCTION_SIZE)
 
 #endif
diff --git a/drivers/media/video/cx25821/cx25821-cards.c b/drivers/media/video/cx25821/cx25821-cards.c
index 6ace603..99988c9 100644
--- a/drivers/media/video/cx25821/cx25821-cards.c
+++ b/drivers/media/video/cx25821/cx25821-cards.c
@@ -67,6 +67,6 @@
 	if (dev->i2c_bus[0].i2c_rc == 0) {
 		dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1;
 		tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom,
-			      sizeof(eeprom));
+				sizeof(eeprom));
 	}
 }
diff --git a/drivers/media/video/cx25821/cx25821-core.c b/drivers/media/video/cx25821/cx25821-core.c
index a7fa38f..f617474 100644
--- a/drivers/media/video/cx25821/cx25821-core.c
+++ b/drivers/media/video/cx25821/cx25821-core.c
@@ -804,8 +804,8 @@
 			      u32 format)
 {
 	if (channel_select <= 7 && channel_select >= 0) {
-		cx_write(dev->channels[channel_select].
-			sram_channels->pix_frmt, format);
+		cx_write(dev->channels[channel_select].sram_channels->pix_frmt,
+				format);
 		dev->channels[channel_select].pixel_formats = format;
 	}
 }
@@ -855,21 +855,19 @@
 	}
 
 	cx25821_sram_channel_setup_audio(dev,
-				dev->channels[SRAM_CH08].sram_channels,
-				128, 0);
+			dev->channels[SRAM_CH08].sram_channels, 128, 0);
 
 	cx25821_gpio_init(dev);
 }
 
 static int cx25821_get_resources(struct cx25821_dev *dev)
 {
-	if (request_mem_region
-	    (pci_resource_start(dev->pci, 0), pci_resource_len(dev->pci, 0),
-	     dev->name))
+	if (request_mem_region(pci_resource_start(dev->pci, 0),
+				pci_resource_len(dev->pci, 0), dev->name))
 		return 0;
 
 	pr_err("%s: can't get MMIO memory @ 0x%llx\n",
-	       dev->name, (unsigned long long)pci_resource_start(dev->pci, 0));
+		dev->name, (unsigned long long)pci_resource_start(dev->pci, 0));
 
 	return -EBUSY;
 }
@@ -972,8 +970,7 @@
 	dev->lmmio = ioremap(dev->base_io_addr, pci_resource_len(dev->pci, 0));
 
 	if (!dev->lmmio) {
-		CX25821_ERR
-		    ("ioremap failed, maybe increasing __VMALLOC_RESERVE in page.h\n");
+		CX25821_ERR("ioremap failed, maybe increasing __VMALLOC_RESERVE in page.h\n");
 		cx25821_iounmap(dev);
 		return -ENOMEM;
 	}
@@ -994,7 +991,7 @@
  *  cx25821_i2c_register(&dev->i2c_bus[2]); */
 
 	CX25821_INFO("i2c register! bus->i2c_rc = %d\n",
-		     dev->i2c_bus[0].i2c_rc);
+			dev->i2c_bus[0].i2c_rc);
 
 	cx25821_card_setup(dev);
 
@@ -1004,9 +1001,8 @@
 	cx25821_video_register(dev);
 
 	/* register IOCTL device */
-	dev->ioctl_dev =
-	   cx25821_vdev_init(dev, dev->pci, &cx25821_videoioctl_template,
-			      "video");
+	dev->ioctl_dev = cx25821_vdev_init(dev, dev->pci,
+			&cx25821_videoioctl_template, "video");
 
 	if (video_register_device
 	    (dev->ioctl_dev, VFL_TYPE_GRABBER, VIDEO_IOCTL_CH) < 0) {
@@ -1103,16 +1099,15 @@
 		}
 		if (bpl <= sg_dma_len(sg) - offset) {
 			/* fits into current chunk */
-			*(rp++) =
-			    cpu_to_le32(RISC_WRITE | RISC_SOL | RISC_EOL | bpl);
+			*(rp++) = cpu_to_le32(RISC_WRITE | RISC_SOL | RISC_EOL |
+					bpl);
 			*(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
 			*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
 			offset += bpl;
 		} else {
 			/* scanline needs to be split */
 			todo = bpl;
-			*(rp++) =
-			    cpu_to_le32(RISC_WRITE | RISC_SOL |
+			*(rp++) = cpu_to_le32(RISC_WRITE | RISC_SOL |
 					(sg_dma_len(sg) - offset));
 			*(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
 			*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
@@ -1120,8 +1115,8 @@
 			offset = 0;
 			sg++;
 			while (todo > sg_dma_len(sg)) {
-				*(rp++) =
-				    cpu_to_le32(RISC_WRITE | sg_dma_len(sg));
+				*(rp++) = cpu_to_le32(RISC_WRITE |
+						sg_dma_len(sg));
 				*(rp++) = cpu_to_le32(sg_dma_address(sg));
 				*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
 				todo -= sg_dma_len(sg);
@@ -1160,8 +1155,8 @@
 	   can cause next bpl to start close to a page border.  First DMA
 	   region may be smaller than PAGE_SIZE */
 	/* write and jump need and extra dword */
-	instructions =
-	    fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
+	instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE +
+			lines);
 	instructions += 2;
 	rc = btcx_riscmem_alloc(pci, risc, instructions * 12);
 
@@ -1215,8 +1210,8 @@
 
 		if (bpl <= sg_dma_len(sg) - offset) {
 			/* fits into current chunk */
-			*(rp++) =
-			    cpu_to_le32(RISC_WRITE | sol | RISC_EOL | bpl);
+			*(rp++) = cpu_to_le32(RISC_WRITE | sol | RISC_EOL |
+					bpl);
 			*(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
 			*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
 			offset += bpl;
@@ -1224,7 +1219,7 @@
 			/* scanline needs to be split */
 			todo = bpl;
 			*(rp++) = cpu_to_le32(RISC_WRITE | sol |
-					      (sg_dma_len(sg) - offset));
+					(sg_dma_len(sg) - offset));
 			*(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
 			*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
 			todo -= (sg_dma_len(sg) - offset);
@@ -1232,7 +1227,7 @@
 			sg++;
 			while (todo > sg_dma_len(sg)) {
 				*(rp++) = cpu_to_le32(RISC_WRITE |
-						      sg_dma_len(sg));
+						sg_dma_len(sg));
 				*(rp++) = cpu_to_le32(sg_dma_address(sg));
 				*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
 				todo -= sg_dma_len(sg);
@@ -1339,8 +1334,8 @@
 				sram_channels->int_stat);
 
 			if (vid_status)
-				handled +=
-				cx25821_video_irq(dev, i, vid_status);
+				handled += cx25821_video_irq(dev, i,
+						vid_status);
 
 			cx_write(PCI_INT_STAT, mask[i]);
 		}
@@ -1427,9 +1422,8 @@
 		goto fail_irq;
 	}
 
-	err =
-	    request_irq(pci_dev->irq, cx25821_irq, IRQF_SHARED,
-			dev->name, dev);
+	err = request_irq(pci_dev->irq, cx25821_irq,
+			IRQF_SHARED, dev->name, dev);
 
 	if (err < 0) {
 		pr_err("%s: can't get IRQ %d\n", dev->name, pci_dev->irq);
@@ -1512,6 +1506,5 @@
 	pci_unregister_driver(&cx25821_pci_driver);
 }
 
-
 module_init(cx25821_init);
 module_exit(cx25821_fini);
diff --git a/drivers/media/video/cx25821/cx25821-i2c.c b/drivers/media/video/cx25821/cx25821-i2c.c
index 4d3d0ce..12d7300 100644
--- a/drivers/media/video/cx25821/cx25821-i2c.c
+++ b/drivers/media/video/cx25821/cx25821-i2c.c
@@ -252,8 +252,8 @@
 		} else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
 			   msgs[i].addr == msgs[i + 1].addr) {
 			/* write then read from same address */
-			retval =
-			    i2c_sendbytes(i2c_adap, &msgs[i], msgs[i + 1].len);
+			retval = i2c_sendbytes(i2c_adap, &msgs[i],
+					msgs[i + 1].len);
 
 			if (retval < 0)
 				goto err;
@@ -276,10 +276,8 @@
 
 static u32 cx25821_functionality(struct i2c_adapter *adap)
 {
-	return I2C_FUNC_SMBUS_EMUL |
-	    I2C_FUNC_I2C |
-	    I2C_FUNC_SMBUS_WORD_DATA |
-	    I2C_FUNC_SMBUS_READ_WORD_DATA | I2C_FUNC_SMBUS_WRITE_WORD_DATA;
+	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C | I2C_FUNC_SMBUS_WORD_DATA |
+		I2C_FUNC_SMBUS_READ_WORD_DATA | I2C_FUNC_SMBUS_WRITE_WORD_DATA;
 }
 
 static struct i2c_algorithm cx25821_i2c_algo_template = {
@@ -300,7 +298,7 @@
 	.name = "cx25821 internal",
 };
 
-/* init + register i2c algo-bit adapter */
+/* init + register i2c adapter */
 int cx25821_i2c_register(struct cx25821_i2c *bus)
 {
 	struct cx25821_dev *dev = bus->dev;
diff --git a/drivers/media/video/cx25821/cx25821-medusa-defines.h b/drivers/media/video/cx25821/cx25821-medusa-defines.h
index 60d197f..7a9e647 100644
--- a/drivers/media/video/cx25821/cx25821-medusa-defines.h
+++ b/drivers/media/video/cx25821/cx25821-medusa-defines.h
@@ -23,7 +23,7 @@
 #ifndef _MEDUSA_DEF_H_
 #define _MEDUSA_DEF_H_
 
-/* Video deocder that we supported */
+/* Video decoder that we supported */
 #define VDEC_A		0
 #define VDEC_B		1
 #define VDEC_C		2
@@ -34,9 +34,9 @@
 #define VDEC_H		7
 
 /* end of display sequence */
-#define END_OF_SEQ					0xF;
+#define END_OF_SEQ	0xF;
 
 /* registry string size */
-#define MAX_REGISTRY_SZ					40;
+#define MAX_REGISTRY_SZ	40;
 
 #endif
diff --git a/drivers/media/video/cx25821/cx25821-medusa-reg.h b/drivers/media/video/cx25821/cx25821-medusa-reg.h
index 1c1c228..c98ac94 100644
--- a/drivers/media/video/cx25821/cx25821-medusa-reg.h
+++ b/drivers/media/video/cx25821/cx25821-medusa-reg.h
@@ -28,22 +28,22 @@
 #define	HOST_REGISTER2				0x0001
 
 /* Chip Configuration Registers */
-#define	CHIP_CTRL					0x0100
-#define	AFE_AB_CTRL					0x0104
-#define	AFE_CD_CTRL					0x0108
-#define	AFE_EF_CTRL					0x010C
-#define	AFE_GH_CTRL					0x0110
+#define	CHIP_CTRL				0x0100
+#define	AFE_AB_CTRL				0x0104
+#define	AFE_CD_CTRL				0x0108
+#define	AFE_EF_CTRL				0x010C
+#define	AFE_GH_CTRL				0x0110
 #define	DENC_AB_CTRL				0x0114
-#define	BYP_AB_CTRL					0x0118
-#define	MON_A_CTRL					0x011C
-#define	DISP_SEQ_A					0x0120
-#define	DISP_SEQ_B					0x0124
-#define	DISP_AB_CNT					0x0128
-#define	DISP_CD_CNT					0x012C
-#define	DISP_EF_CNT					0x0130
-#define	DISP_GH_CNT					0x0134
-#define	DISP_IJ_CNT					0x0138
-#define	PIN_OE_CTRL					0x013C
+#define	BYP_AB_CTRL				0x0118
+#define	MON_A_CTRL				0x011C
+#define	DISP_SEQ_A				0x0120
+#define	DISP_SEQ_B				0x0124
+#define	DISP_AB_CNT				0x0128
+#define	DISP_CD_CNT				0x012C
+#define	DISP_EF_CNT				0x0130
+#define	DISP_GH_CNT				0x0134
+#define	DISP_IJ_CNT				0x0138
+#define	PIN_OE_CTRL				0x013C
 #define	PIN_SPD_CTRL				0x0140
 #define	PIN_SPD_CTRL2				0x0144
 #define	IRQ_STAT_CTRL				0x0148
@@ -51,8 +51,8 @@
 #define	POWER_CTRL_CD				0x0150
 #define	POWER_CTRL_EF				0x0154
 #define	POWER_CTRL_GH				0x0158
-#define	TUNE_CTRL					0x015C
-#define	BIAS_CTRL					0x0160
+#define	TUNE_CTRL				0x015C
+#define	BIAS_CTRL				0x0160
 #define	AFE_AB_DIAG_CTRL			0x0164
 #define	AFE_CD_DIAG_CTRL			0x0168
 #define	AFE_EF_DIAG_CTRL			0x016C
@@ -61,17 +61,17 @@
 #define	PLL_CD_DIAG_CTRL			0x0178
 #define	PLL_EF_DIAG_CTRL			0x017C
 #define	PLL_GH_DIAG_CTRL			0x0180
-#define	TEST_CTRL					0x0184
-#define	BIST_STAT					0x0188
-#define	BIST_STAT2					0x018C
-#define	BIST_VID_PLL_AB_STAT		0x0190
-#define	BIST_VID_PLL_CD_STAT		0x0194
-#define	BIST_VID_PLL_EF_STAT		0x0198
-#define	BIST_VID_PLL_GH_STAT		0x019C
+#define	TEST_CTRL				0x0184
+#define	BIST_STAT				0x0188
+#define	BIST_STAT2				0x018C
+#define	BIST_VID_PLL_AB_STAT			0x0190
+#define	BIST_VID_PLL_CD_STAT			0x0194
+#define	BIST_VID_PLL_EF_STAT			0x0198
+#define	BIST_VID_PLL_GH_STAT			0x019C
 #define	DLL_DIAG_CTRL				0x01A0
 #define	DEV_CH_ID_CTRL				0x01A4
 #define	ABIST_CTRL_STATUS			0x01A8
-#define	ABIST_FREQ					0x01AC
+#define	ABIST_FREQ				0x01AC
 #define	ABIST_GOERT_SHIFT			0x01B0
 #define	ABIST_COEF12				0x01B4
 #define	ABIST_COEF34				0x01B8
@@ -92,357 +92,357 @@
 #define	ABIST_CLAMP_E				0x01F4
 #define	ABIST_CLAMP_F				0x01F8
 
-/*              Digital Video Encoder A Registers */
-#define	DENC_A_REG_1					0x0200
-#define	DENC_A_REG_2					0x0204
-#define	DENC_A_REG_3					0x0208
-#define	DENC_A_REG_4					0x020C
-#define	DENC_A_REG_5					0x0210
-#define	DENC_A_REG_6					0x0214
-#define	DENC_A_REG_7					0x0218
-#define	DENC_A_REG_8					0x021C
+/* Digital Video Encoder A Registers */
+#define	DENC_A_REG_1				0x0200
+#define	DENC_A_REG_2				0x0204
+#define	DENC_A_REG_3				0x0208
+#define	DENC_A_REG_4				0x020C
+#define	DENC_A_REG_5				0x0210
+#define	DENC_A_REG_6				0x0214
+#define	DENC_A_REG_7				0x0218
+#define	DENC_A_REG_8				0x021C
 
-/*      Digital Video Encoder B Registers */
-#define	DENC_B_REG_1					0x0300
-#define	DENC_B_REG_2					0x0304
-#define	DENC_B_REG_3					0x0308
-#define	DENC_B_REG_4					0x030C
-#define	DENC_B_REG_5					0x0310
-#define	DENC_B_REG_6					0x0314
-#define	DENC_B_REG_7					0x0318
-#define	DENC_B_REG_8					0x031C
+/* Digital Video Encoder B Registers */
+#define	DENC_B_REG_1				0x0300
+#define	DENC_B_REG_2				0x0304
+#define	DENC_B_REG_3				0x0308
+#define	DENC_B_REG_4				0x030C
+#define	DENC_B_REG_5				0x0310
+#define	DENC_B_REG_6				0x0314
+#define	DENC_B_REG_7				0x0318
+#define	DENC_B_REG_8				0x031C
 
-/*              Video Decoder A Registers */
-#define	MODE_CTRL						0x1000
-#define	OUT_CTRL1						0x1004
-#define	OUT_CTRL_NS						0x1008
-#define	GEN_STAT						0x100C
-#define	INT_STAT_MASK					0x1010
-#define	LUMA_CTRL						0x1014
-#define	CHROMA_CTRL						0x1018
-#define	CRUSH_CTRL						0x101C
-#define	HORIZ_TIM_CTRL					0x1020
-#define	VERT_TIM_CTRL					0x1024
-#define	MISC_TIM_CTRL					0x1028
-#define	FIELD_COUNT						0x102C
-#define	HSCALE_CTRL						0x1030
-#define	VSCALE_CTRL						0x1034
-#define	MAN_VGA_CTRL					0x1038
-#define	MAN_AGC_CTRL					0x103C
-#define	DFE_CTRL1						0x1040
-#define	DFE_CTRL2						0x1044
-#define	DFE_CTRL3						0x1048
-#define	PLL_CTRL						0x104C
-#define	PLL_CTRL_FAST					0x1050
-#define	HTL_CTRL						0x1054
-#define	SRC_CFG							0x1058
-#define	SC_STEP_SIZE					0x105C
-#define	SC_CONVERGE_CTRL				0x1060
-#define	SC_LOOP_CTRL					0x1064
-#define	COMB_2D_HFS_CFG					0x1068
-#define	COMB_2D_HFD_CFG					0x106C
-#define	COMB_2D_LF_CFG					0x1070
-#define	COMB_2D_BLEND					0x1074
-#define	COMB_MISC_CTRL					0x1078
+/* Video Decoder A Registers */
+#define	MODE_CTRL				0x1000
+#define	OUT_CTRL1				0x1004
+#define	OUT_CTRL_NS				0x1008
+#define	GEN_STAT				0x100C
+#define	INT_STAT_MASK				0x1010
+#define	LUMA_CTRL				0x1014
+#define	CHROMA_CTRL				0x1018
+#define	CRUSH_CTRL				0x101C
+#define	HORIZ_TIM_CTRL				0x1020
+#define	VERT_TIM_CTRL				0x1024
+#define	MISC_TIM_CTRL				0x1028
+#define	FIELD_COUNT				0x102C
+#define	HSCALE_CTRL				0x1030
+#define	VSCALE_CTRL				0x1034
+#define	MAN_VGA_CTRL				0x1038
+#define	MAN_AGC_CTRL				0x103C
+#define	DFE_CTRL1				0x1040
+#define	DFE_CTRL2				0x1044
+#define	DFE_CTRL3				0x1048
+#define	PLL_CTRL				0x104C
+#define	PLL_CTRL_FAST				0x1050
+#define	HTL_CTRL				0x1054
+#define	SRC_CFG					0x1058
+#define	SC_STEP_SIZE				0x105C
+#define	SC_CONVERGE_CTRL			0x1060
+#define	SC_LOOP_CTRL				0x1064
+#define	COMB_2D_HFS_CFG				0x1068
+#define	COMB_2D_HFD_CFG				0x106C
+#define	COMB_2D_LF_CFG				0x1070
+#define	COMB_2D_BLEND				0x1074
+#define	COMB_MISC_CTRL				0x1078
 #define	COMB_FLAT_THRESH_CTRL			0x107C
-#define	COMB_TEST						0x1080
-#define	BP_MISC_CTRL					0x1084
-#define	VCR_DET_CTRL					0x1088
-#define	NOISE_DET_CTRL					0x108C
+#define	COMB_TEST				0x1080
+#define	BP_MISC_CTRL				0x1084
+#define	VCR_DET_CTRL				0x1088
+#define	NOISE_DET_CTRL				0x108C
 #define	COMB_FLAT_NOISE_CTRL			0x1090
-#define	VERSION							0x11F8
-#define	SOFT_RST_CTRL					0x11FC
+#define	VERSION					0x11F8
+#define	SOFT_RST_CTRL				0x11FC
 
-/*      Video Decoder B Registers */
-#define	VDEC_B_MODE_CTRL				0x1200
-#define	VDEC_B_OUT_CTRL1				0x1204
-#define	VDEC_B_OUT_CTRL_NS				0x1208
-#define	VDEC_B_GEN_STAT					0x120C
+/* Video Decoder B Registers */
+#define	VDEC_B_MODE_CTRL			0x1200
+#define	VDEC_B_OUT_CTRL1			0x1204
+#define	VDEC_B_OUT_CTRL_NS			0x1208
+#define	VDEC_B_GEN_STAT				0x120C
 #define	VDEC_B_INT_STAT_MASK			0x1210
-#define	VDEC_B_LUMA_CTRL				0x1214
-#define	VDEC_B_CHROMA_CTRL				0x1218
-#define	VDEC_B_CRUSH_CTRL				0x121C
+#define	VDEC_B_LUMA_CTRL			0x1214
+#define	VDEC_B_CHROMA_CTRL			0x1218
+#define	VDEC_B_CRUSH_CTRL			0x121C
 #define	VDEC_B_HORIZ_TIM_CTRL			0x1220
 #define	VDEC_B_VERT_TIM_CTRL			0x1224
 #define	VDEC_B_MISC_TIM_CTRL			0x1228
-#define	VDEC_B_FIELD_COUNT				0x122C
-#define	VDEC_B_HSCALE_CTRL				0x1230
-#define	VDEC_B_VSCALE_CTRL				0x1234
-#define	VDEC_B_MAN_VGA_CTRL				0x1238
-#define	VDEC_B_MAN_AGC_CTRL				0x123C
-#define	VDEC_B_DFE_CTRL1				0x1240
-#define	VDEC_B_DFE_CTRL2				0x1244
-#define	VDEC_B_DFE_CTRL3				0x1248
-#define	VDEC_B_PLL_CTRL					0x124C
+#define	VDEC_B_FIELD_COUNT			0x122C
+#define	VDEC_B_HSCALE_CTRL			0x1230
+#define	VDEC_B_VSCALE_CTRL			0x1234
+#define	VDEC_B_MAN_VGA_CTRL			0x1238
+#define	VDEC_B_MAN_AGC_CTRL			0x123C
+#define	VDEC_B_DFE_CTRL1			0x1240
+#define	VDEC_B_DFE_CTRL2			0x1244
+#define	VDEC_B_DFE_CTRL3			0x1248
+#define	VDEC_B_PLL_CTRL				0x124C
 #define	VDEC_B_PLL_CTRL_FAST			0x1250
-#define	VDEC_B_HTL_CTRL					0x1254
-#define	VDEC_B_SRC_CFG					0x1258
-#define	VDEC_B_SC_STEP_SIZE				0x125C
+#define	VDEC_B_HTL_CTRL				0x1254
+#define	VDEC_B_SRC_CFG				0x1258
+#define	VDEC_B_SC_STEP_SIZE			0x125C
 #define	VDEC_B_SC_CONVERGE_CTRL			0x1260
-#define	VDEC_B_SC_LOOP_CTRL				0x1264
+#define	VDEC_B_SC_LOOP_CTRL			0x1264
 #define	VDEC_B_COMB_2D_HFS_CFG			0x1268
 #define	VDEC_B_COMB_2D_HFD_CFG			0x126C
 #define	VDEC_B_COMB_2D_LF_CFG			0x1270
 #define	VDEC_B_COMB_2D_BLEND			0x1274
 #define	VDEC_B_COMB_MISC_CTRL			0x1278
-#define	VDEC_B_COMB_FLAT_THRESH_CTRL	0x127C
-#define	VDEC_B_COMB_TEST				0x1280
-#define	VDEC_B_BP_MISC_CTRL				0x1284
-#define	VDEC_B_VCR_DET_CTRL				0x1288
+#define	VDEC_B_COMB_FLAT_THRESH_CTRL		0x127C
+#define	VDEC_B_COMB_TEST			0x1280
+#define	VDEC_B_BP_MISC_CTRL			0x1284
+#define	VDEC_B_VCR_DET_CTRL			0x1288
 #define	VDEC_B_NOISE_DET_CTRL			0x128C
 #define	VDEC_B_COMB_FLAT_NOISE_CTRL		0x1290
-#define	VDEC_B_VERSION					0x13F8
+#define	VDEC_B_VERSION				0x13F8
 #define	VDEC_B_SOFT_RST_CTRL			0x13FC
 
 /* Video Decoder C Registers */
-#define	VDEC_C_MODE_CTRL				0x1400
-#define	VDEC_C_OUT_CTRL1				0x1404
-#define	VDEC_C_OUT_CTRL_NS				0x1408
-#define	VDEC_C_GEN_STAT					0x140C
+#define	VDEC_C_MODE_CTRL			0x1400
+#define	VDEC_C_OUT_CTRL1			0x1404
+#define	VDEC_C_OUT_CTRL_NS			0x1408
+#define	VDEC_C_GEN_STAT				0x140C
 #define	VDEC_C_INT_STAT_MASK			0x1410
-#define VDEC_C_LUMA_CTRL				0x1414
-#define VDEC_C_CHROMA_CTRL				0x1418
-#define	VDEC_C_CRUSH_CTRL				0x141C
+#define VDEC_C_LUMA_CTRL			0x1414
+#define VDEC_C_CHROMA_CTRL			0x1418
+#define	VDEC_C_CRUSH_CTRL			0x141C
 #define	VDEC_C_HORIZ_TIM_CTRL			0x1420
 #define	VDEC_C_VERT_TIM_CTRL			0x1424
 #define	VDEC_C_MISC_TIM_CTRL			0x1428
-#define	VDEC_C_FIELD_COUNT				0x142C
-#define	VDEC_C_HSCALE_CTRL				0x1430
-#define	VDEC_C_VSCALE_CTRL				0x1434
-#define	VDEC_C_MAN_VGA_CTRL				0x1438
-#define	VDEC_C_MAN_AGC_CTRL				0x143C
-#define	VDEC_C_DFE_CTRL1				0x1440
-#define	VDEC_C_DFE_CTRL2				0x1444
-#define	VDEC_C_DFE_CTRL3				0x1448
-#define	VDEC_C_PLL_CTRL					0x144C
+#define	VDEC_C_FIELD_COUNT			0x142C
+#define	VDEC_C_HSCALE_CTRL			0x1430
+#define	VDEC_C_VSCALE_CTRL			0x1434
+#define	VDEC_C_MAN_VGA_CTRL			0x1438
+#define	VDEC_C_MAN_AGC_CTRL			0x143C
+#define	VDEC_C_DFE_CTRL1			0x1440
+#define	VDEC_C_DFE_CTRL2			0x1444
+#define	VDEC_C_DFE_CTRL3			0x1448
+#define	VDEC_C_PLL_CTRL				0x144C
 #define	VDEC_C_PLL_CTRL_FAST			0x1450
-#define	VDEC_C_HTL_CTRL					0x1454
-#define	VDEC_C_SRC_CFG					0x1458
-#define	VDEC_C_SC_STEP_SIZE				0x145C
+#define	VDEC_C_HTL_CTRL				0x1454
+#define	VDEC_C_SRC_CFG				0x1458
+#define	VDEC_C_SC_STEP_SIZE			0x145C
 #define	VDEC_C_SC_CONVERGE_CTRL			0x1460
-#define	VDEC_C_SC_LOOP_CTRL				0x1464
+#define	VDEC_C_SC_LOOP_CTRL			0x1464
 #define	VDEC_C_COMB_2D_HFS_CFG			0x1468
 #define	VDEC_C_COMB_2D_HFD_CFG			0x146C
 #define	VDEC_C_COMB_2D_LF_CFG			0x1470
 #define	VDEC_C_COMB_2D_BLEND			0x1474
 #define	VDEC_C_COMB_MISC_CTRL			0x1478
-#define	VDEC_C_COMB_FLAT_THRESH_CTRL	0x147C
-#define	VDEC_C_COMB_TEST				0x1480
-#define	VDEC_C_BP_MISC_CTRL				0x1484
-#define	VDEC_C_VCR_DET_CTRL				0x1488
+#define	VDEC_C_COMB_FLAT_THRESH_CTRL		0x147C
+#define	VDEC_C_COMB_TEST			0x1480
+#define	VDEC_C_BP_MISC_CTRL			0x1484
+#define	VDEC_C_VCR_DET_CTRL			0x1488
 #define	VDEC_C_NOISE_DET_CTRL			0x148C
 #define	VDEC_C_COMB_FLAT_NOISE_CTRL		0x1490
-#define	VDEC_C_VERSION					0x15F8
+#define	VDEC_C_VERSION				0x15F8
 #define	VDEC_C_SOFT_RST_CTRL			0x15FC
 
 /* Video Decoder D Registers */
-#define VDEC_D_MODE_CTRL				0x1600
-#define VDEC_D_OUT_CTRL1				0x1604
-#define VDEC_D_OUT_CTRL_NS				0x1608
-#define VDEC_D_GEN_STAT					0x160C
+#define VDEC_D_MODE_CTRL			0x1600
+#define VDEC_D_OUT_CTRL1			0x1604
+#define VDEC_D_OUT_CTRL_NS			0x1608
+#define VDEC_D_GEN_STAT				0x160C
 #define VDEC_D_INT_STAT_MASK			0x1610
-#define VDEC_D_LUMA_CTRL				0x1614
-#define VDEC_D_CHROMA_CTRL				0x1618
-#define VDEC_D_CRUSH_CTRL				0x161C
+#define VDEC_D_LUMA_CTRL			0x1614
+#define VDEC_D_CHROMA_CTRL			0x1618
+#define VDEC_D_CRUSH_CTRL			0x161C
 #define VDEC_D_HORIZ_TIM_CTRL			0x1620
 #define VDEC_D_VERT_TIM_CTRL			0x1624
 #define VDEC_D_MISC_TIM_CTRL			0x1628
-#define VDEC_D_FIELD_COUNT				0x162C
-#define VDEC_D_HSCALE_CTRL				0x1630
-#define VDEC_D_VSCALE_CTRL				0x1634
-#define VDEC_D_MAN_VGA_CTRL				0x1638
-#define VDEC_D_MAN_AGC_CTRL				0x163C
-#define VDEC_D_DFE_CTRL1				0x1640
-#define VDEC_D_DFE_CTRL2				0x1644
-#define VDEC_D_DFE_CTRL3				0x1648
-#define VDEC_D_PLL_CTRL					0x164C
+#define VDEC_D_FIELD_COUNT			0x162C
+#define VDEC_D_HSCALE_CTRL			0x1630
+#define VDEC_D_VSCALE_CTRL			0x1634
+#define VDEC_D_MAN_VGA_CTRL			0x1638
+#define VDEC_D_MAN_AGC_CTRL			0x163C
+#define VDEC_D_DFE_CTRL1			0x1640
+#define VDEC_D_DFE_CTRL2			0x1644
+#define VDEC_D_DFE_CTRL3			0x1648
+#define VDEC_D_PLL_CTRL				0x164C
 #define VDEC_D_PLL_CTRL_FAST			0x1650
-#define VDEC_D_HTL_CTRL					0x1654
-#define VDEC_D_SRC_CFG					0x1658
-#define VDEC_D_SC_STEP_SIZE				0x165C
+#define VDEC_D_HTL_CTRL				0x1654
+#define VDEC_D_SRC_CFG				0x1658
+#define VDEC_D_SC_STEP_SIZE			0x165C
 #define VDEC_D_SC_CONVERGE_CTRL			0x1660
-#define VDEC_D_SC_LOOP_CTRL				0x1664
+#define VDEC_D_SC_LOOP_CTRL			0x1664
 #define VDEC_D_COMB_2D_HFS_CFG			0x1668
 #define VDEC_D_COMB_2D_HFD_CFG			0x166C
 #define VDEC_D_COMB_2D_LF_CFG			0x1670
 #define VDEC_D_COMB_2D_BLEND			0x1674
 #define VDEC_D_COMB_MISC_CTRL			0x1678
-#define VDEC_D_COMB_FLAT_THRESH_CTRL	0x167C
-#define VDEC_D_COMB_TEST				0x1680
-#define VDEC_D_BP_MISC_CTRL				0x1684
-#define VDEC_D_VCR_DET_CTRL				0x1688
+#define VDEC_D_COMB_FLAT_THRESH_CTRL		0x167C
+#define VDEC_D_COMB_TEST			0x1680
+#define VDEC_D_BP_MISC_CTRL			0x1684
+#define VDEC_D_VCR_DET_CTRL			0x1688
 #define VDEC_D_NOISE_DET_CTRL			0x168C
 #define VDEC_D_COMB_FLAT_NOISE_CTRL		0x1690
-#define VDEC_D_VERSION					0x17F8
+#define VDEC_D_VERSION				0x17F8
 #define VDEC_D_SOFT_RST_CTRL			0x17FC
 
 /* Video Decoder E Registers */
-#define	VDEC_E_MODE_CTRL				0x1800
-#define	VDEC_E_OUT_CTRL1				0x1804
-#define	VDEC_E_OUT_CTRL_NS				0x1808
-#define	VDEC_E_GEN_STAT					0x180C
+#define	VDEC_E_MODE_CTRL			0x1800
+#define	VDEC_E_OUT_CTRL1			0x1804
+#define	VDEC_E_OUT_CTRL_NS			0x1808
+#define	VDEC_E_GEN_STAT				0x180C
 #define	VDEC_E_INT_STAT_MASK			0x1810
-#define	VDEC_E_LUMA_CTRL				0x1814
-#define	VDEC_E_CHROMA_CTRL				0x1818
-#define	VDEC_E_CRUSH_CTRL				0x181C
+#define	VDEC_E_LUMA_CTRL			0x1814
+#define	VDEC_E_CHROMA_CTRL			0x1818
+#define	VDEC_E_CRUSH_CTRL			0x181C
 #define	VDEC_E_HORIZ_TIM_CTRL			0x1820
 #define	VDEC_E_VERT_TIM_CTRL			0x1824
 #define	VDEC_E_MISC_TIM_CTRL			0x1828
-#define	VDEC_E_FIELD_COUNT				0x182C
-#define	VDEC_E_HSCALE_CTRL				0x1830
-#define	VDEC_E_VSCALE_CTRL				0x1834
-#define	VDEC_E_MAN_VGA_CTRL				0x1838
-#define	VDEC_E_MAN_AGC_CTRL				0x183C
-#define	VDEC_E_DFE_CTRL1				0x1840
-#define	VDEC_E_DFE_CTRL2				0x1844
-#define	VDEC_E_DFE_CTRL3				0x1848
-#define	VDEC_E_PLL_CTRL					0x184C
+#define	VDEC_E_FIELD_COUNT			0x182C
+#define	VDEC_E_HSCALE_CTRL			0x1830
+#define	VDEC_E_VSCALE_CTRL			0x1834
+#define	VDEC_E_MAN_VGA_CTRL			0x1838
+#define	VDEC_E_MAN_AGC_CTRL			0x183C
+#define	VDEC_E_DFE_CTRL1			0x1840
+#define	VDEC_E_DFE_CTRL2			0x1844
+#define	VDEC_E_DFE_CTRL3			0x1848
+#define	VDEC_E_PLL_CTRL				0x184C
 #define	VDEC_E_PLL_CTRL_FAST			0x1850
-#define	VDEC_E_HTL_CTRL					0x1854
-#define	VDEC_E_SRC_CFG					0x1858
-#define	VDEC_E_SC_STEP_SIZE				0x185C
+#define	VDEC_E_HTL_CTRL				0x1854
+#define	VDEC_E_SRC_CFG				0x1858
+#define	VDEC_E_SC_STEP_SIZE			0x185C
 #define	VDEC_E_SC_CONVERGE_CTRL			0x1860
-#define	VDEC_E_SC_LOOP_CTRL				0x1864
+#define	VDEC_E_SC_LOOP_CTRL			0x1864
 #define	VDEC_E_COMB_2D_HFS_CFG			0x1868
 #define	VDEC_E_COMB_2D_HFD_CFG			0x186C
 #define	VDEC_E_COMB_2D_LF_CFG			0x1870
 #define	VDEC_E_COMB_2D_BLEND			0x1874
 #define	VDEC_E_COMB_MISC_CTRL			0x1878
-#define	VDEC_E_COMB_FLAT_THRESH_CTRL	0x187C
-#define	VDEC_E_COMB_TEST				0x1880
-#define	VDEC_E_BP_MISC_CTRL				0x1884
-#define	VDEC_E_VCR_DET_CTRL				0x1888
+#define	VDEC_E_COMB_FLAT_THRESH_CTRL		0x187C
+#define	VDEC_E_COMB_TEST			0x1880
+#define	VDEC_E_BP_MISC_CTRL			0x1884
+#define	VDEC_E_VCR_DET_CTRL			0x1888
 #define	VDEC_E_NOISE_DET_CTRL			0x188C
 #define	VDEC_E_COMB_FLAT_NOISE_CTRL		0x1890
-#define	VDEC_E_VERSION					0x19F8
+#define	VDEC_E_VERSION				0x19F8
 #define	VDEC_E_SOFT_RST_CTRL			0x19FC
 
 /* Video Decoder F Registers */
-#define	VDEC_F_MODE_CTRL				0x1A00
-#define	VDEC_F_OUT_CTRL1				0x1A04
-#define	VDEC_F_OUT_CTRL_NS				0x1A08
-#define	VDEC_F_GEN_STAT					0x1A0C
+#define	VDEC_F_MODE_CTRL			0x1A00
+#define	VDEC_F_OUT_CTRL1			0x1A04
+#define	VDEC_F_OUT_CTRL_NS			0x1A08
+#define	VDEC_F_GEN_STAT				0x1A0C
 #define	VDEC_F_INT_STAT_MASK			0x1A10
-#define	VDEC_F_LUMA_CTRL				0x1A14
-#define	VDEC_F_CHROMA_CTRL				0x1A18
-#define	VDEC_F_CRUSH_CTRL				0x1A1C
+#define	VDEC_F_LUMA_CTRL			0x1A14
+#define	VDEC_F_CHROMA_CTRL			0x1A18
+#define	VDEC_F_CRUSH_CTRL			0x1A1C
 #define	VDEC_F_HORIZ_TIM_CTRL			0x1A20
 #define	VDEC_F_VERT_TIM_CTRL			0x1A24
 #define	VDEC_F_MISC_TIM_CTRL			0x1A28
-#define	VDEC_F_FIELD_COUNT				0x1A2C
-#define	VDEC_F_HSCALE_CTRL				0x1A30
-#define	VDEC_F_VSCALE_CTRL				0x1A34
-#define	VDEC_F_MAN_VGA_CTRL				0x1A38
-#define	VDEC_F_MAN_AGC_CTRL				0x1A3C
-#define	VDEC_F_DFE_CTRL1				0x1A40
-#define	VDEC_F_DFE_CTRL2				0x1A44
-#define	VDEC_F_DFE_CTRL3				0x1A48
-#define	VDEC_F_PLL_CTRL					0x1A4C
+#define	VDEC_F_FIELD_COUNT			0x1A2C
+#define	VDEC_F_HSCALE_CTRL			0x1A30
+#define	VDEC_F_VSCALE_CTRL			0x1A34
+#define	VDEC_F_MAN_VGA_CTRL			0x1A38
+#define	VDEC_F_MAN_AGC_CTRL			0x1A3C
+#define	VDEC_F_DFE_CTRL1			0x1A40
+#define	VDEC_F_DFE_CTRL2			0x1A44
+#define	VDEC_F_DFE_CTRL3			0x1A48
+#define	VDEC_F_PLL_CTRL				0x1A4C
 #define	VDEC_F_PLL_CTRL_FAST			0x1A50
-#define	VDEC_F_HTL_CTRL					0x1A54
-#define	VDEC_F_SRC_CFG					0x1A58
-#define	VDEC_F_SC_STEP_SIZE				0x1A5C
+#define	VDEC_F_HTL_CTRL				0x1A54
+#define	VDEC_F_SRC_CFG				0x1A58
+#define	VDEC_F_SC_STEP_SIZE			0x1A5C
 #define	VDEC_F_SC_CONVERGE_CTRL			0x1A60
-#define	VDEC_F_SC_LOOP_CTRL				0x1A64
+#define	VDEC_F_SC_LOOP_CTRL			0x1A64
 #define	VDEC_F_COMB_2D_HFS_CFG			0x1A68
 #define	VDEC_F_COMB_2D_HFD_CFG			0x1A6C
 #define	VDEC_F_COMB_2D_LF_CFG			0x1A70
 #define	VDEC_F_COMB_2D_BLEND			0x1A74
 #define	VDEC_F_COMB_MISC_CTRL			0x1A78
-#define	VDEC_F_COMB_FLAT_THRESH_CTRL	0x1A7C
-#define	VDEC_F_COMB_TEST				0x1A80
-#define	VDEC_F_BP_MISC_CTRL				0x1A84
-#define	VDEC_F_VCR_DET_CTRL				0x1A88
+#define	VDEC_F_COMB_FLAT_THRESH_CTRL		0x1A7C
+#define	VDEC_F_COMB_TEST			0x1A80
+#define	VDEC_F_BP_MISC_CTRL			0x1A84
+#define	VDEC_F_VCR_DET_CTRL			0x1A88
 #define	VDEC_F_NOISE_DET_CTRL			0x1A8C
 #define	VDEC_F_COMB_FLAT_NOISE_CTRL		0x1A90
-#define	VDEC_F_VERSION					0x1BF8
+#define	VDEC_F_VERSION				0x1BF8
 #define	VDEC_F_SOFT_RST_CTRL			0x1BFC
 
 /* Video Decoder G Registers */
-#define	VDEC_G_MODE_CTRL				0x1C00
-#define	VDEC_G_OUT_CTRL1				0x1C04
-#define	VDEC_G_OUT_CTRL_NS				0x1C08
-#define	VDEC_G_GEN_STAT					0x1C0C
+#define	VDEC_G_MODE_CTRL			0x1C00
+#define	VDEC_G_OUT_CTRL1			0x1C04
+#define	VDEC_G_OUT_CTRL_NS			0x1C08
+#define	VDEC_G_GEN_STAT				0x1C0C
 #define	VDEC_G_INT_STAT_MASK			0x1C10
-#define	VDEC_G_LUMA_CTRL				0x1C14
-#define	VDEC_G_CHROMA_CTRL				0x1C18
-#define	VDEC_G_CRUSH_CTRL				0x1C1C
+#define	VDEC_G_LUMA_CTRL			0x1C14
+#define	VDEC_G_CHROMA_CTRL			0x1C18
+#define	VDEC_G_CRUSH_CTRL			0x1C1C
 #define	VDEC_G_HORIZ_TIM_CTRL			0x1C20
 #define	VDEC_G_VERT_TIM_CTRL			0x1C24
 #define	VDEC_G_MISC_TIM_CTRL			0x1C28
-#define	VDEC_G_FIELD_COUNT				0x1C2C
-#define	VDEC_G_HSCALE_CTRL				0x1C30
-#define	VDEC_G_VSCALE_CTRL				0x1C34
-#define	VDEC_G_MAN_VGA_CTRL				0x1C38
-#define	VDEC_G_MAN_AGC_CTRL				0x1C3C
-#define	VDEC_G_DFE_CTRL1				0x1C40
-#define	VDEC_G_DFE_CTRL2				0x1C44
-#define	VDEC_G_DFE_CTRL3				0x1C48
-#define	VDEC_G_PLL_CTRL					0x1C4C
+#define	VDEC_G_FIELD_COUNT			0x1C2C
+#define	VDEC_G_HSCALE_CTRL			0x1C30
+#define	VDEC_G_VSCALE_CTRL			0x1C34
+#define	VDEC_G_MAN_VGA_CTRL			0x1C38
+#define	VDEC_G_MAN_AGC_CTRL			0x1C3C
+#define	VDEC_G_DFE_CTRL1			0x1C40
+#define	VDEC_G_DFE_CTRL2			0x1C44
+#define	VDEC_G_DFE_CTRL3			0x1C48
+#define	VDEC_G_PLL_CTRL				0x1C4C
 #define	VDEC_G_PLL_CTRL_FAST			0x1C50
-#define	VDEC_G_HTL_CTRL					0x1C54
-#define	VDEC_G_SRC_CFG					0x1C58
-#define	VDEC_G_SC_STEP_SIZE				0x1C5C
+#define	VDEC_G_HTL_CTRL				0x1C54
+#define	VDEC_G_SRC_CFG				0x1C58
+#define	VDEC_G_SC_STEP_SIZE			0x1C5C
 #define	VDEC_G_SC_CONVERGE_CTRL			0x1C60
-#define	VDEC_G_SC_LOOP_CTRL				0x1C64
+#define	VDEC_G_SC_LOOP_CTRL			0x1C64
 #define	VDEC_G_COMB_2D_HFS_CFG			0x1C68
 #define	VDEC_G_COMB_2D_HFD_CFG			0x1C6C
 #define	VDEC_G_COMB_2D_LF_CFG			0x1C70
 #define	VDEC_G_COMB_2D_BLEND			0x1C74
 #define	VDEC_G_COMB_MISC_CTRL			0x1C78
-#define	VDEC_G_COMB_FLAT_THRESH_CTRL	0x1C7C
-#define	VDEC_G_COMB_TEST				0x1C80
-#define	VDEC_G_BP_MISC_CTRL				0x1C84
-#define	VDEC_G_VCR_DET_CTRL				0x1C88
+#define	VDEC_G_COMB_FLAT_THRESH_CTRL		0x1C7C
+#define	VDEC_G_COMB_TEST			0x1C80
+#define	VDEC_G_BP_MISC_CTRL			0x1C84
+#define	VDEC_G_VCR_DET_CTRL			0x1C88
 #define	VDEC_G_NOISE_DET_CTRL			0x1C8C
 #define	VDEC_G_COMB_FLAT_NOISE_CTRL		0x1C90
-#define	VDEC_G_VERSION					0x1DF8
+#define	VDEC_G_VERSION				0x1DF8
 #define	VDEC_G_SOFT_RST_CTRL			0x1DFC
 
-/*              Video Decoder H Registers  */
-#define	VDEC_H_MODE_CTRL				0x1E00
-#define	VDEC_H_OUT_CTRL1				0x1E04
-#define	VDEC_H_OUT_CTRL_NS				0x1E08
-#define	VDEC_H_GEN_STAT					0x1E0C
+/* Video Decoder H Registers  */
+#define	VDEC_H_MODE_CTRL			0x1E00
+#define	VDEC_H_OUT_CTRL1			0x1E04
+#define	VDEC_H_OUT_CTRL_NS			0x1E08
+#define	VDEC_H_GEN_STAT				0x1E0C
 #define	VDEC_H_INT_STAT_MASK			0x1E1E
-#define	VDEC_H_LUMA_CTRL				0x1E14
-#define	VDEC_H_CHROMA_CTRL				0x1E18
-#define	VDEC_H_CRUSH_CTRL				0x1E1C
+#define	VDEC_H_LUMA_CTRL			0x1E14
+#define	VDEC_H_CHROMA_CTRL			0x1E18
+#define	VDEC_H_CRUSH_CTRL			0x1E1C
 #define	VDEC_H_HORIZ_TIM_CTRL			0x1E20
 #define	VDEC_H_VERT_TIM_CTRL			0x1E24
 #define	VDEC_H_MISC_TIM_CTRL			0x1E28
-#define	VDEC_H_FIELD_COUNT				0x1E2C
-#define	VDEC_H_HSCALE_CTRL				0x1E30
-#define	VDEC_H_VSCALE_CTRL				0x1E34
-#define	VDEC_H_MAN_VGA_CTRL				0x1E38
-#define	VDEC_H_MAN_AGC_CTRL				0x1E3C
-#define	VDEC_H_DFE_CTRL1				0x1E40
-#define	VDEC_H_DFE_CTRL2				0x1E44
-#define	VDEC_H_DFE_CTRL3				0x1E48
-#define	VDEC_H_PLL_CTRL					0x1E4C
+#define	VDEC_H_FIELD_COUNT			0x1E2C
+#define	VDEC_H_HSCALE_CTRL			0x1E30
+#define	VDEC_H_VSCALE_CTRL			0x1E34
+#define	VDEC_H_MAN_VGA_CTRL			0x1E38
+#define	VDEC_H_MAN_AGC_CTRL			0x1E3C
+#define	VDEC_H_DFE_CTRL1			0x1E40
+#define	VDEC_H_DFE_CTRL2			0x1E44
+#define	VDEC_H_DFE_CTRL3			0x1E48
+#define	VDEC_H_PLL_CTRL				0x1E4C
 #define	VDEC_H_PLL_CTRL_FAST			0x1E50
-#define	VDEC_H_HTL_CTRL					0x1E54
-#define	VDEC_H_SRC_CFG					0x1E58
-#define	VDEC_H_SC_STEP_SIZE				0x1E5C
+#define	VDEC_H_HTL_CTRL				0x1E54
+#define	VDEC_H_SRC_CFG				0x1E58
+#define	VDEC_H_SC_STEP_SIZE			0x1E5C
 #define	VDEC_H_SC_CONVERGE_CTRL			0x1E60
-#define	VDEC_H_SC_LOOP_CTRL				0x1E64
+#define	VDEC_H_SC_LOOP_CTRL			0x1E64
 #define	VDEC_H_COMB_2D_HFS_CFG			0x1E68
 #define	VDEC_H_COMB_2D_HFD_CFG			0x1E6C
 #define	VDEC_H_COMB_2D_LF_CFG			0x1E70
 #define	VDEC_H_COMB_2D_BLEND			0x1E74
 #define	VDEC_H_COMB_MISC_CTRL			0x1E78
-#define	VDEC_H_COMB_FLAT_THRESH_CTRL	0x1E7C
-#define	VDEC_H_COMB_TEST				0x1E80
-#define	VDEC_H_BP_MISC_CTRL				0x1E84
-#define	VDEC_H_VCR_DET_CTRL				0x1E88
+#define	VDEC_H_COMB_FLAT_THRESH_CTRL		0x1E7C
+#define	VDEC_H_COMB_TEST			0x1E80
+#define	VDEC_H_BP_MISC_CTRL			0x1E84
+#define	VDEC_H_VCR_DET_CTRL			0x1E88
 #define	VDEC_H_NOISE_DET_CTRL			0x1E8C
 #define	VDEC_H_COMB_FLAT_NOISE_CTRL		0x1E90
-#define	VDEC_H_VERSION					0x1FF8
+#define	VDEC_H_VERSION				0x1FF8
 #define	VDEC_H_SOFT_RST_CTRL			0x1FFC
 
 /*****************************************************************************/
 /* LUMA_CTRL register fields */
-#define VDEC_A_BRITE_CTRL				0x1014
+#define VDEC_A_BRITE_CTRL			0x1014
 #define VDEC_A_CNTRST_CTRL			0x1015
 #define VDEC_A_PEAK_SEL				0x1016
 
diff --git a/drivers/media/video/cx25821/cx25821-medusa-video.c b/drivers/media/video/cx25821/cx25821-medusa-video.c
index fc780d0..298a68d 100644
--- a/drivers/media/video/cx25821/cx25821-medusa-video.c
+++ b/drivers/media/video/cx25821/cx25821-medusa-video.c
@@ -99,82 +99,67 @@
 
 	for (i = 0; i < MAX_DECODERS; i++) {
 		/* set video format NTSC-M */
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
-				     &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				MODE_CTRL + (0x200 * i), &tmp);
 		value &= 0xFFFFFFF0;
 		/* enable the fast locking mode bit[16] */
 		value |= 0x10001;
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
-				      value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				MODE_CTRL + (0x200 * i), value);
 
 		/* resolution NTSC 720x480 */
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0],
-				     HORIZ_TIM_CTRL + (0x200 * i), &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				HORIZ_TIM_CTRL + (0x200 * i), &tmp);
 		value &= 0x00C00C00;
 		value |= 0x612D0074;
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      HORIZ_TIM_CTRL + (0x200 * i), value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				HORIZ_TIM_CTRL + (0x200 * i), value);
 
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0],
-				     VERT_TIM_CTRL + (0x200 * i), &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				VERT_TIM_CTRL + (0x200 * i), &tmp);
 		value &= 0x00C00C00;
 		value |= 0x1C1E001A;	/* vblank_cnt + 2 to get camera ID */
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      VERT_TIM_CTRL + (0x200 * i), value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				VERT_TIM_CTRL + (0x200 * i), value);
 
 		/* chroma subcarrier step size */
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      SC_STEP_SIZE + (0x200 * i), 0x43E00000);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				SC_STEP_SIZE + (0x200 * i), 0x43E00000);
 
 		/* enable VIP optional active */
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0],
-				     OUT_CTRL_NS + (0x200 * i), &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				OUT_CTRL_NS + (0x200 * i), &tmp);
 		value &= 0xFFFBFFFF;
 		value |= 0x00040000;
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      OUT_CTRL_NS + (0x200 * i), value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				OUT_CTRL_NS + (0x200 * i), value);
 
 		/* enable VIP optional active (VIP_OPT_AL) for direct output. */
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
-				     &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				OUT_CTRL1 + (0x200 * i), &tmp);
 		value &= 0xFFFBFFFF;
 		value |= 0x00040000;
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
-				      value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				OUT_CTRL1 + (0x200 * i), value);
 
 		/*
 		 * clear VPRES_VERT_EN bit, fixes the chroma run away problem
 		 * when the input switching rate < 16 fields
 		*/
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0],
-				     MISC_TIM_CTRL + (0x200 * i), &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				MISC_TIM_CTRL + (0x200 * i), &tmp);
 		/* disable special play detection */
 		value = setBitAtPos(value, 14);
 		value = clearBitAtPos(value, 15);
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      MISC_TIM_CTRL + (0x200 * i), value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				MISC_TIM_CTRL + (0x200 * i), value);
 
 		/* set vbi_gate_en to 0 */
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
-				     &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				DFE_CTRL1 + (0x200 * i), &tmp);
 		value = clearBitAtPos(value, 29);
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
-				      value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				DFE_CTRL1 + (0x200 * i), value);
 
 		/* Enable the generation of blue field output if no video */
 		medusa_enable_bluefield_output(dev, i, 1);
@@ -182,61 +167,49 @@
 
 	for (i = 0; i < MAX_ENCODERS; i++) {
 		/* NTSC hclock */
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0],
-				     DENC_A_REG_1 + (0x100 * i), &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				DENC_A_REG_1 + (0x100 * i), &tmp);
 		value &= 0xF000FC00;
 		value |= 0x06B402D0;
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      DENC_A_REG_1 + (0x100 * i), value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				DENC_A_REG_1 + (0x100 * i), value);
 
 		/* burst begin and burst end */
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0],
-				     DENC_A_REG_2 + (0x100 * i), &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				DENC_A_REG_2 + (0x100 * i), &tmp);
 		value &= 0xFF000000;
 		value |= 0x007E9054;
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      DENC_A_REG_2 + (0x100 * i), value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				DENC_A_REG_2 + (0x100 * i), value);
 
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0],
-				     DENC_A_REG_3 + (0x100 * i), &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				DENC_A_REG_3 + (0x100 * i), &tmp);
 		value &= 0xFC00FE00;
 		value |= 0x00EC00F0;
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      DENC_A_REG_3 + (0x100 * i), value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				DENC_A_REG_3 + (0x100 * i), value);
 
 		/* set NTSC vblank, no phase alternation, 7.5 IRE pedestal */
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0],
-				     DENC_A_REG_4 + (0x100 * i), &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				DENC_A_REG_4 + (0x100 * i), &tmp);
 		value &= 0x00FCFFFF;
 		value |= 0x13020000;
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      DENC_A_REG_4 + (0x100 * i), value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				DENC_A_REG_4 + (0x100 * i), value);
 
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0],
-				     DENC_A_REG_5 + (0x100 * i), &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				DENC_A_REG_5 + (0x100 * i), &tmp);
 		value &= 0xFFFF0000;
 		value |= 0x0000E575;
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      DENC_A_REG_5 + (0x100 * i), value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				DENC_A_REG_5 + (0x100 * i), value);
 
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      DENC_A_REG_6 + (0x100 * i), 0x009A89C1);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				DENC_A_REG_6 + (0x100 * i), 0x009A89C1);
 
 		/* Subcarrier Increment */
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      DENC_A_REG_7 + (0x100 * i), 0x21F07C1F);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				DENC_A_REG_7 + (0x100 * i), 0x21F07C1F);
 	}
 
 	/* set picture resolutions */
@@ -261,34 +234,27 @@
 	u32 value = 0, tmp = 0;
 
 	/* Setup for 2D threshold */
-	ret_val =
-	    cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFS_CFG + (0x200 * dec),
-			      0x20002861);
-	ret_val =
-	    cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFD_CFG + (0x200 * dec),
-			      0x20002861);
-	ret_val =
-	    cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_LF_CFG + (0x200 * dec),
-			      0x200A1023);
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+			COMB_2D_HFS_CFG + (0x200 * dec), 0x20002861);
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+			COMB_2D_HFD_CFG + (0x200 * dec), 0x20002861);
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+			COMB_2D_LF_CFG + (0x200 * dec), 0x200A1023);
 
 	/* Setup flat chroma and luma thresholds */
-	value =
-	    cx25821_i2c_read(&dev->i2c_bus[0],
-			     COMB_FLAT_THRESH_CTRL + (0x200 * dec), &tmp);
+	value = cx25821_i2c_read(&dev->i2c_bus[0],
+			COMB_FLAT_THRESH_CTRL + (0x200 * dec), &tmp);
 	value &= 0x06230000;
-	ret_val =
-	    cx25821_i2c_write(&dev->i2c_bus[0],
-			      COMB_FLAT_THRESH_CTRL + (0x200 * dec), value);
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+			COMB_FLAT_THRESH_CTRL + (0x200 * dec), value);
 
 	/* set comb 2D blend */
-	ret_val =
-	    cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_BLEND + (0x200 * dec),
-			      0x210F0F0F);
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+			COMB_2D_BLEND + (0x200 * dec), 0x210F0F0F);
 
 	/* COMB MISC CONTROL */
-	ret_val =
-	    cx25821_i2c_write(&dev->i2c_bus[0], COMB_MISC_CTRL + (0x200 * dec),
-			      0x41120A7F);
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+			COMB_MISC_CTRL + (0x200 * dec), 0x41120A7F);
 
 	return ret_val;
 }
@@ -304,83 +270,68 @@
 
 	for (i = 0; i < MAX_DECODERS; i++) {
 		/* set video format PAL-BDGHI */
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
-				     &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				MODE_CTRL + (0x200 * i), &tmp);
 		value &= 0xFFFFFFF0;
 		/* enable the fast locking mode bit[16] */
 		value |= 0x10004;
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
-				      value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				MODE_CTRL + (0x200 * i), value);
 
 		/* resolution PAL 720x576 */
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0],
-				     HORIZ_TIM_CTRL + (0x200 * i), &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				HORIZ_TIM_CTRL + (0x200 * i), &tmp);
 		value &= 0x00C00C00;
 		value |= 0x632D007D;
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      HORIZ_TIM_CTRL + (0x200 * i), value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				HORIZ_TIM_CTRL + (0x200 * i), value);
 
 		/* vblank656_cnt=x26, vactive_cnt=240h, vblank_cnt=x24 */
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0],
-				     VERT_TIM_CTRL + (0x200 * i), &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				VERT_TIM_CTRL + (0x200 * i), &tmp);
 		value &= 0x00C00C00;
 		value |= 0x28240026;	/* vblank_cnt + 2 to get camera ID */
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      VERT_TIM_CTRL + (0x200 * i), value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				VERT_TIM_CTRL + (0x200 * i), value);
 
 		/* chroma subcarrier step size */
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      SC_STEP_SIZE + (0x200 * i), 0x5411E2D0);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				SC_STEP_SIZE + (0x200 * i), 0x5411E2D0);
 
 		/* enable VIP optional active */
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0],
-				     OUT_CTRL_NS + (0x200 * i), &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				OUT_CTRL_NS + (0x200 * i), &tmp);
 		value &= 0xFFFBFFFF;
 		value |= 0x00040000;
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      OUT_CTRL_NS + (0x200 * i), value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				OUT_CTRL_NS + (0x200 * i), value);
 
 		/* enable VIP optional active (VIP_OPT_AL) for direct output. */
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
-				     &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				OUT_CTRL1 + (0x200 * i), &tmp);
 		value &= 0xFFFBFFFF;
 		value |= 0x00040000;
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
-				      value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				OUT_CTRL1 + (0x200 * i), value);
 
 		/*
 		 * clear VPRES_VERT_EN bit, fixes the chroma run away problem
 		 * when the input switching rate < 16 fields
 		 */
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0],
-				     MISC_TIM_CTRL + (0x200 * i), &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				MISC_TIM_CTRL + (0x200 * i), &tmp);
 		/* disable special play detection */
 		value = setBitAtPos(value, 14);
 		value = clearBitAtPos(value, 15);
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      MISC_TIM_CTRL + (0x200 * i), value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				MISC_TIM_CTRL + (0x200 * i), value);
 
 		/* set vbi_gate_en to 0 */
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
-				     &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				DFE_CTRL1 + (0x200 * i), &tmp);
 		value = clearBitAtPos(value, 29);
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
-				      value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				DFE_CTRL1 + (0x200 * i), value);
 
 		medusa_PALCombInit(dev, i);
 
@@ -390,62 +341,50 @@
 
 	for (i = 0; i < MAX_ENCODERS; i++) {
 		/* PAL hclock */
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0],
-				     DENC_A_REG_1 + (0x100 * i), &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				DENC_A_REG_1 + (0x100 * i), &tmp);
 		value &= 0xF000FC00;
 		value |= 0x06C002D0;
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      DENC_A_REG_1 + (0x100 * i), value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				DENC_A_REG_1 + (0x100 * i), value);
 
 		/* burst begin and burst end */
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0],
-				     DENC_A_REG_2 + (0x100 * i), &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				DENC_A_REG_2 + (0x100 * i), &tmp);
 		value &= 0xFF000000;
 		value |= 0x007E9754;
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      DENC_A_REG_2 + (0x100 * i), value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				DENC_A_REG_2 + (0x100 * i), value);
 
 		/* hblank and vactive */
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0],
-				     DENC_A_REG_3 + (0x100 * i), &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				DENC_A_REG_3 + (0x100 * i), &tmp);
 		value &= 0xFC00FE00;
 		value |= 0x00FC0120;
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      DENC_A_REG_3 + (0x100 * i), value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				DENC_A_REG_3 + (0x100 * i), value);
 
 		/* set PAL vblank, phase alternation, 0 IRE pedestal */
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0],
-				     DENC_A_REG_4 + (0x100 * i), &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				DENC_A_REG_4 + (0x100 * i), &tmp);
 		value &= 0x00FCFFFF;
 		value |= 0x14010000;
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      DENC_A_REG_4 + (0x100 * i), value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				DENC_A_REG_4 + (0x100 * i), value);
 
-		value =
-		    cx25821_i2c_read(&dev->i2c_bus[0],
-				     DENC_A_REG_5 + (0x100 * i), &tmp);
+		value = cx25821_i2c_read(&dev->i2c_bus[0],
+				DENC_A_REG_5 + (0x100 * i), &tmp);
 		value &= 0xFFFF0000;
 		value |= 0x0000F078;
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      DENC_A_REG_5 + (0x100 * i), value);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				DENC_A_REG_5 + (0x100 * i), value);
 
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      DENC_A_REG_6 + (0x100 * i), 0x00A493CF);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				DENC_A_REG_6 + (0x100 * i), 0x00A493CF);
 
 		/* Subcarrier Increment */
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      DENC_A_REG_7 + (0x100 * i), 0x2A098ACB);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				DENC_A_REG_7 + (0x100 * i), 0x2A098ACB);
 	}
 
 	/* set picture resolutions */
@@ -499,7 +438,7 @@
 
 	mutex_lock(&dev->lock);
 
-	/* validate the width - cannot be negative */
+	/* validate the width */
 	if (width > MAX_WIDTH) {
 		pr_info("%s(): width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH\n",
 			__func__, width, MAX_WIDTH);
@@ -543,12 +482,10 @@
 
 	for (; decoder < decoder_count; decoder++) {
 		/* write scaling values for each decoder */
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      HSCALE_CTRL + (0x200 * decoder), hscale);
-		ret_val =
-		    cx25821_i2c_write(&dev->i2c_bus[0],
-				      VSCALE_CTRL + (0x200 * decoder), vscale);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				HSCALE_CTRL + (0x200 * decoder), hscale);
+		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
+				VSCALE_CTRL + (0x200 * decoder), vscale);
 	}
 
 	mutex_unlock(&dev->lock);
@@ -606,8 +543,8 @@
 }
 
 /* Map to Medusa register setting */
-static int mapM(int srcMin,
-		int srcMax, int srcVal, int dstMin, int dstMax, int *dstVal)
+static int mapM(int srcMin, int srcMax, int srcVal, int dstMin, int dstMax,
+		int *dstVal)
 {
 	int numerator;
 	int denominator;
@@ -654,23 +591,19 @@
 	u32 val = 0, tmp = 0;
 
 	mutex_lock(&dev->lock);
-	if ((brightness > VIDEO_PROCAMP_MAX)
-	    || (brightness < VIDEO_PROCAMP_MIN)) {
+	if ((brightness > VIDEO_PROCAMP_MAX) ||
+	    (brightness < VIDEO_PROCAMP_MIN)) {
 		mutex_unlock(&dev->lock);
 		return -1;
 	}
-	ret_val =
-	    mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness,
-		 SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
+	ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness,
+			SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
 	value = convert_to_twos(value, 8);
-	val =
-	    cx25821_i2c_read(&dev->i2c_bus[0],
-			     VDEC_A_BRITE_CTRL + (0x200 * decoder), &tmp);
+	val = cx25821_i2c_read(&dev->i2c_bus[0],
+			VDEC_A_BRITE_CTRL + (0x200 * decoder), &tmp);
 	val &= 0xFFFFFF00;
-	ret_val |=
-	    cx25821_i2c_write(&dev->i2c_bus[0],
-			      VDEC_A_BRITE_CTRL + (0x200 * decoder),
-			      val | value);
+	ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
+			VDEC_A_BRITE_CTRL + (0x200 * decoder), val | value);
 	mutex_unlock(&dev->lock);
 	return ret_val;
 }
@@ -688,17 +621,13 @@
 		return -1;
 	}
 
-	ret_val =
-	    mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, contrast,
-		 UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
-	val =
-	    cx25821_i2c_read(&dev->i2c_bus[0],
-			     VDEC_A_CNTRST_CTRL + (0x200 * decoder), &tmp);
+	ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, contrast,
+			UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
+	val = cx25821_i2c_read(&dev->i2c_bus[0],
+			VDEC_A_CNTRST_CTRL + (0x200 * decoder), &tmp);
 	val &= 0xFFFFFF00;
-	ret_val |=
-	    cx25821_i2c_write(&dev->i2c_bus[0],
-			      VDEC_A_CNTRST_CTRL + (0x200 * decoder),
-			      val | value);
+	ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
+			VDEC_A_CNTRST_CTRL + (0x200 * decoder), val | value);
 
 	mutex_unlock(&dev->lock);
 	return ret_val;
@@ -717,19 +646,16 @@
 		return -1;
 	}
 
-	ret_val =
-	    mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue, SIGNED_BYTE_MIN,
-		 SIGNED_BYTE_MAX, &value);
+	ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue,
+			SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
 
 	value = convert_to_twos(value, 8);
-	val =
-	    cx25821_i2c_read(&dev->i2c_bus[0],
-			     VDEC_A_HUE_CTRL + (0x200 * decoder), &tmp);
+	val = cx25821_i2c_read(&dev->i2c_bus[0],
+			VDEC_A_HUE_CTRL + (0x200 * decoder), &tmp);
 	val &= 0xFFFFFF00;
 
-	ret_val |=
-	    cx25821_i2c_write(&dev->i2c_bus[0],
-			      VDEC_A_HUE_CTRL + (0x200 * decoder), val | value);
+	ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
+			VDEC_A_HUE_CTRL + (0x200 * decoder), val | value);
 
 	mutex_unlock(&dev->lock);
 	return ret_val;
@@ -743,33 +669,26 @@
 
 	mutex_lock(&dev->lock);
 
-	if ((saturation > VIDEO_PROCAMP_MAX)
-	    || (saturation < VIDEO_PROCAMP_MIN)) {
+	if ((saturation > VIDEO_PROCAMP_MAX) ||
+	    (saturation < VIDEO_PROCAMP_MIN)) {
 		mutex_unlock(&dev->lock);
 		return -1;
 	}
 
-	ret_val =
-	    mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation,
-		 UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
+	ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation,
+			UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
 
-	val =
-	    cx25821_i2c_read(&dev->i2c_bus[0],
-			     VDEC_A_USAT_CTRL + (0x200 * decoder), &tmp);
+	val = cx25821_i2c_read(&dev->i2c_bus[0],
+			VDEC_A_USAT_CTRL + (0x200 * decoder), &tmp);
 	val &= 0xFFFFFF00;
-	ret_val |=
-	    cx25821_i2c_write(&dev->i2c_bus[0],
-			      VDEC_A_USAT_CTRL + (0x200 * decoder),
-			      val | value);
+	ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
+			VDEC_A_USAT_CTRL + (0x200 * decoder), val | value);
 
-	val =
-	    cx25821_i2c_read(&dev->i2c_bus[0],
-			     VDEC_A_VSAT_CTRL + (0x200 * decoder), &tmp);
+	val = cx25821_i2c_read(&dev->i2c_bus[0],
+			VDEC_A_VSAT_CTRL + (0x200 * decoder), &tmp);
 	val &= 0xFFFFFF00;
-	ret_val |=
-	    cx25821_i2c_write(&dev->i2c_bus[0],
-			      VDEC_A_VSAT_CTRL + (0x200 * decoder),
-			      val | value);
+	ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
+			VDEC_A_VSAT_CTRL + (0x200 * decoder), val | value);
 
 	mutex_unlock(&dev->lock);
 	return ret_val;
@@ -830,9 +749,8 @@
 	/* select AFE clock to output mode */
 	value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
 	value &= 0x83FFFFFF;
-	ret_val =
-	   cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL,
-			     value | 0x10000000);
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL,
+			value | 0x10000000);
 
 	if (ret_val < 0)
 		goto error;
diff --git a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c
index 2a724dd..5a157cf 100644
--- a/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c
+++ b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c
@@ -65,9 +65,8 @@
 		*(rp++) = cpu_to_le32(dev->_data_buf_phys_addr_ch2 + offset);
 		*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
 
-		if ((lines <= NTSC_FIELD_HEIGHT)
-		    || (line < (NTSC_FIELD_HEIGHT - 1))
-		    || !(dev->_isNTSC_ch2)) {
+		if ((lines <= NTSC_FIELD_HEIGHT) ||
+		    (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC_ch2)) {
 			offset += dist_betwn_starts;
 		}
 	}
@@ -85,7 +84,7 @@
 {
 	unsigned int line, i;
 	struct sram_channel *sram_ch =
-	   dev->channels[dev->_channel2_upstream_select].sram_channels;
+		dev->channels[dev->_channel2_upstream_select].sram_channels;
 	int dist_betwn_starts = bpl * 2;
 
 	/* sync instruction */
@@ -103,9 +102,8 @@
 		*(rp++) = cpu_to_le32(databuf_phys_addr + offset);
 		*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
 
-		if ((lines <= NTSC_FIELD_HEIGHT)
-		    || (line < (NTSC_FIELD_HEIGHT - 1))
-		    || !(dev->_isNTSC_ch2)) {
+		if ((lines <= NTSC_FIELD_HEIGHT) ||
+		    (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC_ch2)) {
 			offset += dist_betwn_starts;
 		}
 
@@ -173,7 +171,7 @@
 
 		fifo_enable = FIFO_DISABLE;
 
-	       /* Even field */
+		/* Even field */
 		rp = cx25821_risc_field_upstream_ch2(dev, rp,
 				dev->_data_buf_phys_addr_ch2 + databuf_offset,
 				bottom_offset, 0x200, bpl, singlefield_lines,
@@ -189,9 +187,9 @@
 		}
 
 	       /*
-		  Loop to 2ndFrameRISC or to Start of
-		  Risc program & generate IRQ
-	       */
+		* Loop to 2ndFrameRISC or to Start of
+		* Risc program & generate IRQ
+		*/
 		*(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
 		*(rp++) = cpu_to_le32(risc_phys_jump_addr);
 		*(rp++) = cpu_to_le32(0);
@@ -203,7 +201,7 @@
 void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev)
 {
 	struct sram_channel *sram_ch =
-	   dev->channels[VID_UPSTREAM_SRAM_CHANNEL_J].sram_channels;
+		dev->channels[VID_UPSTREAM_SRAM_CHANNEL_J].sram_channels;
 	u32 tmp = 0;
 
 	if (!dev->_is_running_ch2) {
@@ -262,9 +260,8 @@
 	struct file *myfile;
 	int frame_index_temp = dev->_frame_index_ch2;
 	int i = 0;
-	int line_size =
-	    (dev->_pixel_format_ch2 ==
-	     PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
+	int line_size = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ?
+		Y411_LINE_SZ : Y422_LINE_SZ;
 	int frame_size = 0;
 	int frame_offset = 0;
 	ssize_t vfs_read_retval = 0;
@@ -277,14 +274,11 @@
 		return 0;
 
 	if (dev->_isNTSC_ch2) {
-		frame_size =
-		    (line_size ==
-		     Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
-		    FRAME_SIZE_NTSC_Y422;
+		frame_size = (line_size == Y411_LINE_SZ) ?
+			FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422;
 	} else {
-		frame_size =
-		    (line_size ==
-		     Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
+		frame_size = (line_size == Y411_LINE_SZ) ?
+			FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
 	}
 
 	frame_offset = (frame_index_temp > 0) ? frame_size : 0;
@@ -318,14 +312,14 @@
 		for (i = 0; i < dev->_lines_count_ch2; i++) {
 			pos = file_offset;
 
-			vfs_read_retval =
-			    vfs_read(myfile, mybuf, line_size, &pos);
+			vfs_read_retval = vfs_read(myfile, mybuf, line_size,
+					&pos);
 
 			if (vfs_read_retval > 0 && vfs_read_retval == line_size
 			    && dev->_data_buf_virt_addr_ch2 != NULL) {
 				memcpy((void *)(dev->_data_buf_virt_addr_ch2 +
 						frame_offset / 4), mybuf,
-				       vfs_read_retval);
+						vfs_read_retval);
 			}
 
 			file_offset += vfs_read_retval;
@@ -341,8 +335,8 @@
 		if (i > 0)
 			dev->_frame_count_ch2++;
 
-		dev->_file_status_ch2 =
-		    (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
+		dev->_file_status_ch2 = (vfs_read_retval == line_size) ?
+			IN_PROGRESS : END_OF_FILE;
 
 		set_fs(old_fs);
 		filp_close(myfile, NULL);
@@ -353,8 +347,8 @@
 
 static void cx25821_vidups_handler_ch2(struct work_struct *work)
 {
-	struct cx25821_dev *dev =
-	    container_of(work, struct cx25821_dev, _irq_work_entry_ch2);
+	struct cx25821_dev *dev = container_of(work, struct cx25821_dev,
+			_irq_work_entry_ch2);
 
 	if (!dev) {
 		pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n",
@@ -362,18 +356,16 @@
 		return;
 	}
 
-	cx25821_get_frame_ch2(dev,
-			     dev->channels[dev->
-			       _channel2_upstream_select].sram_channels);
+	cx25821_get_frame_ch2(dev, dev->channels[dev->
+			_channel2_upstream_select].sram_channels);
 }
 
 int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
 {
 	struct file *myfile;
 	int i = 0, j = 0;
-	int line_size =
-	    (dev->_pixel_format_ch2 ==
-	     PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
+	int line_size = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ?
+		Y411_LINE_SZ : Y422_LINE_SZ;
 	ssize_t vfs_read_retval = 0;
 	char mybuf[line_size];
 	loff_t pos;
@@ -410,16 +402,16 @@
 			for (i = 0; i < dev->_lines_count_ch2; i++) {
 				pos = offset;
 
-				vfs_read_retval =
-				    vfs_read(myfile, mybuf, line_size, &pos);
+				vfs_read_retval = vfs_read(myfile, mybuf,
+						line_size, &pos);
 
-				if (vfs_read_retval > 0
-				    && vfs_read_retval == line_size
-				    && dev->_data_buf_virt_addr_ch2 != NULL) {
+				if (vfs_read_retval > 0 &&
+				    vfs_read_retval == line_size &&
+				    dev->_data_buf_virt_addr_ch2 != NULL) {
 					memcpy((void *)(dev->
 							_data_buf_virt_addr_ch2
 							+ offset / 4), mybuf,
-					       vfs_read_retval);
+							vfs_read_retval);
 				}
 
 				offset += vfs_read_retval;
@@ -438,8 +430,8 @@
 				break;
 		}
 
-		dev->_file_status_ch2 =
-		    (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
+		dev->_file_status_ch2 = (vfs_read_retval == line_size) ?
+			IN_PROGRESS : END_OF_FILE;
 
 		set_fs(old_fs);
 		myfile->f_pos = 0;
@@ -463,9 +455,8 @@
 				    dev->_dma_phys_addr_ch2);
 	}
 
-	dev->_dma_virt_addr_ch2 =
-	    pci_alloc_consistent(dev->pci, dev->upstream_riscbuf_size_ch2,
-				 &dma_addr);
+	dev->_dma_virt_addr_ch2 = pci_alloc_consistent(dev->pci,
+			dev->upstream_riscbuf_size_ch2, &dma_addr);
 	dev->_dma_virt_start_addr_ch2 = dev->_dma_virt_addr_ch2;
 	dev->_dma_phys_start_addr_ch2 = dma_addr;
 	dev->_dma_phys_addr_ch2 = dma_addr;
@@ -485,9 +476,8 @@
 				    dev->_data_buf_phys_addr_ch2);
 	}
 	/* For Video Data buffer allocation */
-	dev->_data_buf_virt_addr_ch2 =
-	    pci_alloc_consistent(dev->pci, dev->upstream_databuf_size_ch2,
-				 &data_dma_addr);
+	dev->_data_buf_virt_addr_ch2 = pci_alloc_consistent(dev->pci,
+			dev->upstream_databuf_size_ch2, &data_dma_addr);
 	dev->_data_buf_phys_addr_ch2 = data_dma_addr;
 	dev->_data_buf_size_ch2 = dev->upstream_databuf_size_ch2;
 
@@ -563,8 +553,8 @@
 				else
 					line_size_in_bytes = Y422_LINE_SZ;
 				risc_phys_jump_addr =
-				    dev->_dma_phys_start_addr_ch2 +
-				    odd_risc_prog_size;
+					dev->_dma_phys_start_addr_ch2 +
+					odd_risc_prog_size;
 
 				rp = cx25821_update_riscprogram_ch2(dev,
 						dev->_dma_virt_start_addr_ch2,
@@ -612,11 +602,9 @@
 	vid_status = cx_read(sram_ch->int_stat);
 
 	/* Only deal with our interrupt */
-	if (vid_status) {
-		handled =
-		    cx25821_video_upstream_irq_ch2(dev, channel_num,
-						   vid_status);
-	}
+	if (vid_status)
+		handled = cx25821_video_upstream_irq_ch2(dev, channel_num,
+				vid_status);
 
 	if (handled < 0)
 		cx25821_stop_upstream_video_ch2(dev);
@@ -691,8 +679,7 @@
 	tmp = cx_read(sram_ch->int_msk);
 	cx_write(sram_ch->int_msk, tmp |= _intr_msk);
 
-	err =
-	    request_irq(dev->pci->irq, cx25821_upstream_irq_ch2,
+	err = request_irq(dev->pci->irq, cx25821_upstream_irq_ch2,
 			IRQF_SHARED, dev->name, dev);
 	if (err < 0) {
 		pr_err("%s: can't get upstream IRQ %d\n",
@@ -752,45 +739,38 @@
 	dev->_file_status_ch2 = RESET_STATUS;
 	dev->_lines_count_ch2 = dev->_isNTSC_ch2 ? 480 : 576;
 	dev->_pixel_format_ch2 = pixel_format;
-	dev->_line_size_ch2 =
-	    (dev->_pixel_format_ch2 ==
-	     PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
+	dev->_line_size_ch2 = (dev->_pixel_format_ch2 == PIXEL_FRMT_422) ?
+		(WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
 	data_frame_size = dev->_isNTSC_ch2 ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ;
-	risc_buffer_size =
-	    dev->_isNTSC_ch2 ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
+	risc_buffer_size = dev->_isNTSC_ch2 ?
+		NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
 
 	if (dev->input_filename_ch2) {
 		str_length = strlen(dev->input_filename_ch2);
-		dev->_filename_ch2 = kmalloc(str_length + 1, GFP_KERNEL);
+		dev->_filename_ch2 = kmemdup(dev->input_filename_ch2,
+					     str_length + 1, GFP_KERNEL);
 
 		if (!dev->_filename_ch2)
 			goto error;
-
-		memcpy(dev->_filename_ch2, dev->input_filename_ch2,
-		       str_length + 1);
 	} else {
 		str_length = strlen(dev->_defaultname_ch2);
-		dev->_filename_ch2 = kmalloc(str_length + 1, GFP_KERNEL);
+		dev->_filename_ch2 = kmemdup(dev->_defaultname_ch2,
+					     str_length + 1, GFP_KERNEL);
 
 		if (!dev->_filename_ch2)
 			goto error;
-
-		memcpy(dev->_filename_ch2, dev->_defaultname_ch2,
-		       str_length + 1);
 	}
 
 	/* Default if filename is empty string */
 	if (strcmp(dev->input_filename_ch2, "") == 0) {
 		if (dev->_isNTSC_ch2) {
-			dev->_filename_ch2 =
-			    (dev->_pixel_format_ch2 ==
-			     PIXEL_FRMT_411) ? "/root/vid411.yuv" :
-			    "/root/vidtest.yuv";
+			dev->_filename_ch2 = (dev->_pixel_format_ch2 ==
+				PIXEL_FRMT_411) ? "/root/vid411.yuv" :
+				"/root/vidtest.yuv";
 		} else {
-			dev->_filename_ch2 =
-			    (dev->_pixel_format_ch2 ==
-			     PIXEL_FRMT_411) ? "/root/pal411.yuv" :
-			    "/root/pal422.yuv";
+			dev->_filename_ch2 = (dev->_pixel_format_ch2 ==
+				PIXEL_FRMT_411) ? "/root/pal411.yuv" :
+				"/root/pal422.yuv";
 		}
 	}
 
diff --git a/drivers/media/video/cx25821/cx25821-video-upstream.c b/drivers/media/video/cx25821/cx25821-video-upstream.c
index c0b8006..21e7d65 100644
--- a/drivers/media/video/cx25821/cx25821-video-upstream.c
+++ b/drivers/media/video/cx25821/cx25821-video-upstream.c
@@ -136,7 +136,7 @@
 {
 	unsigned int line, i;
 	struct sram_channel *sram_ch =
-	   dev->channels[dev->_channel_upstream_select].sram_channels;
+		dev->channels[dev->_channel_upstream_select].sram_channels;
 	int dist_betwn_starts = bpl * 2;
 
 	/* sync instruction */
@@ -194,15 +194,12 @@
 	if (dev->_isNTSC) {
 		odd_num_lines = singlefield_lines + 1;
 		risc_program_size = FRAME1_VID_PROG_SIZE;
-		frame_size =
-		    (bpl ==
-		     Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
-		    FRAME_SIZE_NTSC_Y422;
+		frame_size = (bpl == Y411_LINE_SZ) ?
+			FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422;
 	} else {
 		risc_program_size = PAL_VID_PROG_SIZE;
-		frame_size =
-		    (bpl ==
-		     Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
+		frame_size = (bpl == Y411_LINE_SZ) ?
+			FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
 	}
 
 	/* Virtual address of Risc buffer program */
@@ -214,13 +211,9 @@
 		if (UNSET != top_offset) {
 			fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE;
 			rp = cx25821_risc_field_upstream(dev, rp,
-							 dev->
-							 _data_buf_phys_addr +
-							 databuf_offset,
-							 top_offset, 0, bpl,
-							 odd_num_lines,
-							 fifo_enable,
-							 ODD_FIELD);
+					dev->_data_buf_phys_addr +
+					databuf_offset, top_offset, 0, bpl,
+					odd_num_lines, fifo_enable, ODD_FIELD);
 		}
 
 		fifo_enable = FIFO_DISABLE;
@@ -234,8 +227,8 @@
 
 		if (frame == 0) {
 			risc_flag = RISC_CNT_RESET;
-			risc_phys_jump_addr =
-			    dev->_dma_phys_start_addr + risc_program_size;
+			risc_phys_jump_addr = dev->_dma_phys_start_addr +
+				risc_program_size;
 		} else {
 			risc_phys_jump_addr = dev->_dma_phys_start_addr;
 			risc_flag = RISC_CNT_INC;
@@ -255,7 +248,7 @@
 void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev)
 {
 	struct sram_channel *sram_ch =
-	   dev->channels[VID_UPSTREAM_SRAM_CHANNEL_I].sram_channels;
+		dev->channels[VID_UPSTREAM_SRAM_CHANNEL_I].sram_channels;
 	u32 tmp = 0;
 
 	if (!dev->_is_running) {
@@ -312,9 +305,8 @@
 	struct file *myfile;
 	int frame_index_temp = dev->_frame_index;
 	int i = 0;
-	int line_size =
-	    (dev->_pixel_format ==
-	     PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
+	int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ?
+		Y411_LINE_SZ : Y422_LINE_SZ;
 	int frame_size = 0;
 	int frame_offset = 0;
 	ssize_t vfs_read_retval = 0;
@@ -326,16 +318,12 @@
 	if (dev->_file_status == END_OF_FILE)
 		return 0;
 
-	if (dev->_isNTSC) {
-		frame_size =
-		    (line_size ==
-		     Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
-		    FRAME_SIZE_NTSC_Y422;
-	} else {
-		frame_size =
-		    (line_size ==
-		     Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
-	}
+	if (dev->_isNTSC)
+		frame_size = (line_size == Y411_LINE_SZ) ?
+			FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422;
+	else
+		frame_size = (line_size == Y411_LINE_SZ) ?
+			FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
 
 	frame_offset = (frame_index_temp > 0) ? frame_size : 0;
 	file_offset = dev->_frame_count * frame_size;
@@ -369,8 +357,8 @@
 		for (i = 0; i < dev->_lines_count; i++) {
 			pos = file_offset;
 
-			vfs_read_retval =
-			    vfs_read(myfile, mybuf, line_size, &pos);
+			vfs_read_retval = vfs_read(myfile, mybuf, line_size,
+					&pos);
 
 			if (vfs_read_retval > 0 && vfs_read_retval == line_size
 			    && dev->_data_buf_virt_addr != NULL) {
@@ -392,8 +380,8 @@
 		if (i > 0)
 			dev->_frame_count++;
 
-		dev->_file_status =
-		    (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
+		dev->_file_status = (vfs_read_retval == line_size) ?
+			IN_PROGRESS : END_OF_FILE;
 
 		set_fs(old_fs);
 		filp_close(myfile, NULL);
@@ -404,8 +392,8 @@
 
 static void cx25821_vidups_handler(struct work_struct *work)
 {
-	struct cx25821_dev *dev =
-	    container_of(work, struct cx25821_dev, _irq_work_entry);
+	struct cx25821_dev *dev = container_of(work, struct cx25821_dev,
+			_irq_work_entry);
 
 	if (!dev) {
 		pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n",
@@ -413,18 +401,16 @@
 		return;
 	}
 
-	cx25821_get_frame(dev,
-			 dev->channels[dev->_channel_upstream_select].
-					       sram_channels);
+	cx25821_get_frame(dev, dev->channels[dev->_channel_upstream_select].
+			sram_channels);
 }
 
 int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
 {
 	struct file *myfile;
 	int i = 0, j = 0;
-	int line_size =
-	    (dev->_pixel_format ==
-	     PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
+	int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ?
+		Y411_LINE_SZ : Y422_LINE_SZ;
 	ssize_t vfs_read_retval = 0;
 	char mybuf[line_size];
 	loff_t pos;
@@ -461,8 +447,8 @@
 			for (i = 0; i < dev->_lines_count; i++) {
 				pos = offset;
 
-				vfs_read_retval =
-				    vfs_read(myfile, mybuf, line_size, &pos);
+				vfs_read_retval = vfs_read(myfile, mybuf,
+						line_size, &pos);
 
 				if (vfs_read_retval > 0
 				    && vfs_read_retval == line_size
@@ -489,8 +475,8 @@
 				break;
 		}
 
-		dev->_file_status =
-		    (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
+		dev->_file_status = (vfs_read_retval == line_size) ?
+			IN_PROGRESS : END_OF_FILE;
 
 		set_fs(old_fs);
 		myfile->f_pos = 0;
@@ -507,14 +493,12 @@
 	dma_addr_t dma_addr;
 	dma_addr_t data_dma_addr;
 
-	if (dev->_dma_virt_addr != NULL) {
+	if (dev->_dma_virt_addr != NULL)
 		pci_free_consistent(dev->pci, dev->upstream_riscbuf_size,
-				    dev->_dma_virt_addr, dev->_dma_phys_addr);
-	}
+				dev->_dma_virt_addr, dev->_dma_phys_addr);
 
-	dev->_dma_virt_addr =
-	    pci_alloc_consistent(dev->pci, dev->upstream_riscbuf_size,
-				 &dma_addr);
+	dev->_dma_virt_addr = pci_alloc_consistent(dev->pci,
+			dev->upstream_riscbuf_size, &dma_addr);
 	dev->_dma_virt_start_addr = dev->_dma_virt_addr;
 	dev->_dma_phys_start_addr = dma_addr;
 	dev->_dma_phys_addr = dma_addr;
@@ -528,15 +512,13 @@
 	/* Clear memory at address */
 	memset(dev->_dma_virt_addr, 0, dev->_risc_size);
 
-	if (dev->_data_buf_virt_addr != NULL) {
+	if (dev->_data_buf_virt_addr != NULL)
 		pci_free_consistent(dev->pci, dev->upstream_databuf_size,
-				    dev->_data_buf_virt_addr,
-				    dev->_data_buf_phys_addr);
-	}
+				dev->_data_buf_virt_addr,
+				dev->_data_buf_phys_addr);
 	/* For Video Data buffer allocation */
-	dev->_data_buf_virt_addr =
-	    pci_alloc_consistent(dev->pci, dev->upstream_databuf_size,
-				 &data_dma_addr);
+	dev->_data_buf_virt_addr = pci_alloc_consistent(dev->pci,
+			dev->upstream_databuf_size, &data_dma_addr);
 	dev->_data_buf_phys_addr = data_dma_addr;
 	dev->_data_buf_size = dev->upstream_databuf_size;
 
@@ -553,9 +535,8 @@
 		return ret;
 
 	/* Create RISC programs */
-	ret =
-	    cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl,
-					 dev->_lines_count);
+	ret = cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl,
+			dev->_lines_count);
 	if (ret < 0) {
 		pr_info("Failed creating Video Upstream Risc programs!\n");
 		goto error;
@@ -672,10 +653,9 @@
 	vid_status = cx_read(sram_ch->int_stat);
 
 	/* Only deal with our interrupt */
-	if (vid_status) {
-		handled =
-		    cx25821_video_upstream_irq(dev, channel_num, vid_status);
-	}
+	if (vid_status)
+		handled = cx25821_video_upstream_irq(dev, channel_num,
+				vid_status);
 
 	if (handled < 0)
 		cx25821_stop_upstream_video_ch1(dev);
@@ -747,8 +727,7 @@
 	tmp = cx_read(sram_ch->int_msk);
 	cx_write(sram_ch->int_msk, tmp |= _intr_msk);
 
-	err =
-	    request_irq(dev->pci->irq, cx25821_upstream_irq,
+	err = request_irq(dev->pci->irq, cx25821_upstream_irq,
 			IRQF_SHARED, dev->name, dev);
 	if (err < 0) {
 		pr_err("%s: can't get upstream IRQ %d\n",
@@ -807,43 +786,38 @@
 	dev->_file_status = RESET_STATUS;
 	dev->_lines_count = dev->_isNTSC ? 480 : 576;
 	dev->_pixel_format = pixel_format;
-	dev->_line_size =
-	    (dev->_pixel_format ==
-	     PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
+	dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ?
+		(WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
 	data_frame_size = dev->_isNTSC ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ;
-	risc_buffer_size =
-	    dev->_isNTSC ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
+	risc_buffer_size = dev->_isNTSC ?
+		NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
 
 	if (dev->input_filename) {
 		str_length = strlen(dev->input_filename);
-		dev->_filename = kmalloc(str_length + 1, GFP_KERNEL);
+		dev->_filename = kmemdup(dev->input_filename, str_length + 1,
+					 GFP_KERNEL);
 
 		if (!dev->_filename)
 			goto error;
-
-		memcpy(dev->_filename, dev->input_filename, str_length + 1);
 	} else {
 		str_length = strlen(dev->_defaultname);
-		dev->_filename = kmalloc(str_length + 1, GFP_KERNEL);
+		dev->_filename = kmemdup(dev->_defaultname, str_length + 1,
+					 GFP_KERNEL);
 
 		if (!dev->_filename)
 			goto error;
-
-		memcpy(dev->_filename, dev->_defaultname, str_length + 1);
 	}
 
 	/* Default if filename is empty string */
 	if (strcmp(dev->input_filename, "") == 0) {
 		if (dev->_isNTSC) {
 			dev->_filename =
-			    (dev->_pixel_format ==
-			     PIXEL_FRMT_411) ? "/root/vid411.yuv" :
-			    "/root/vidtest.yuv";
+				(dev->_pixel_format == PIXEL_FRMT_411) ?
+				"/root/vid411.yuv" : "/root/vidtest.yuv";
 		} else {
 			dev->_filename =
-			    (dev->_pixel_format ==
-			     PIXEL_FRMT_411) ? "/root/pal411.yuv" :
-			    "/root/pal422.yuv";
+				(dev->_pixel_format == PIXEL_FRMT_411) ?
+				"/root/pal411.yuv" : "/root/pal422.yuv";
 		}
 	}
 
@@ -852,13 +826,11 @@
 	dev->_file_status = RESET_STATUS;
 	dev->_lines_count = dev->_isNTSC ? 480 : 576;
 	dev->_pixel_format = pixel_format;
-	dev->_line_size =
-	    (dev->_pixel_format ==
-	     PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
+	dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ?
+		(WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
 
-	retval =
-	    cx25821_sram_channel_setup_upstream(dev, sram_ch, dev->_line_size,
-						0);
+	retval = cx25821_sram_channel_setup_upstream(dev, sram_ch,
+			dev->_line_size, 0);
 
 	/* setup fifo + format */
 	cx25821_set_pixelengine(dev, sram_ch, dev->_pixel_format);
diff --git a/drivers/media/video/cx25821/cx25821-video.c b/drivers/media/video/cx25821/cx25821-video.c
index 4d6907c..ffd8bc7 100644
--- a/drivers/media/video/cx25821/cx25821-video.c
+++ b/drivers/media/video/cx25821/cx25821-video.c
@@ -118,12 +118,12 @@
 
 	if (!list_empty(&q->active)) {
 		list_for_each(item, &q->active)
-		    buf = list_entry(item, struct cx25821_buffer, vb.queue);
+			buf = list_entry(item, struct cx25821_buffer, vb.queue);
 	}
 
 	if (!list_empty(&q->queued)) {
 		list_for_each(item, &q->queued)
-		    buf = list_entry(item, struct cx25821_buffer, vb.queue);
+			buf = list_entry(item, struct cx25821_buffer, vb.queue);
 	}
 
 }
@@ -140,8 +140,8 @@
 			break;
 		}
 
-		buf =
-		    list_entry(q->active.next, struct cx25821_buffer, vb.queue);
+		buf = list_entry(q->active.next, struct cx25821_buffer,
+				vb.queue);
 
 		/* count comes from the hw and it is 16bit wide --
 		 * this trick handles wrap-arounds correctly for
@@ -318,8 +318,8 @@
 	struct list_head *item;
 
 	if (!list_empty(&q->active)) {
-		buf =
-		    list_entry(q->active.next, struct cx25821_buffer, vb.queue);
+		buf = list_entry(q->active.next, struct cx25821_buffer,
+				vb.queue);
 
 		cx25821_start_video_dma(dev, q, buf, channel);
 
@@ -337,8 +337,8 @@
 		if (list_empty(&q->queued))
 			return 0;
 
-		buf =
-		    list_entry(q->queued.next, struct cx25821_buffer, vb.queue);
+		buf = list_entry(q->queued.next, struct cx25821_buffer,
+				vb.queue);
 
 		if (NULL == prev) {
 			list_move_tail(&buf->vb.queue, &q->active);
@@ -375,8 +375,8 @@
 
 	spin_lock_irqsave(&dev->slock, flags);
 	while (!list_empty(&q->active)) {
-		buf =
-		    list_entry(q->active.next, struct cx25821_buffer, vb.queue);
+		buf = list_entry(q->active.next, struct cx25821_buffer,
+				vb.queue);
 		list_del(&buf->vb.queue);
 
 		buf->vb.state = VIDEOBUF_ERROR;
@@ -484,8 +484,7 @@
 		cx25821_init_controls(dev, i);
 
 		cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper,
-				dev->channels[i].sram_channels->dma_ctl,
-				0x11, 0);
+			dev->channels[i].sram_channels->dma_ctl, 0x11, 0);
 
 		dev->channels[i].sram_channels = &cx25821_sram_channels[i];
 		dev->channels[i].video_dev = NULL;
@@ -499,15 +498,14 @@
 		dev->channels[i].timeout_data.dev = dev;
 		dev->channels[i].timeout_data.channel =
 			&cx25821_sram_channels[i];
-		dev->channels[i].vidq.timeout.function =
-			cx25821_vid_timeout;
+		dev->channels[i].vidq.timeout.function = cx25821_vid_timeout;
 		dev->channels[i].vidq.timeout.data =
 			(unsigned long)&dev->channels[i].timeout_data;
 		init_timer(&dev->channels[i].vidq.timeout);
 
 		/* register v4l devices */
-		dev->channels[i].video_dev = cx25821_vdev_init(dev,
-				dev->pci, &cx25821_video_device, "video");
+		dev->channels[i].video_dev = cx25821_vdev_init(dev, dev->pci,
+				&cx25821_video_device, "video");
 
 		err = video_register_device(dev->channels[i].video_dev,
 				VFL_TYPE_GRABBER, video_nr[dev->nr]);
@@ -528,7 +526,6 @@
 #endif
 	mutex_unlock(&dev->lock);
 
-
 	return 0;
 
 fail_unreg:
@@ -558,7 +555,7 @@
 	struct cx25821_fh *fh = q->priv_data;
 	struct cx25821_dev *dev = fh->dev;
 	struct cx25821_buffer *buf =
-	    container_of(vb, struct cx25821_buffer, vb);
+		container_of(vb, struct cx25821_buffer, vb);
 	int rc, init_buffer = 0;
 	u32 line0_offset, line1_offset;
 	struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
@@ -617,14 +614,13 @@
 			if (channel_opened >= 0 && channel_opened <= 7) {
 				if (dev->channels[channel_opened]
 						.use_cif_resolution) {
-					if (dev->tvnorm & V4L2_STD_PAL_BG
-					    || dev->tvnorm & V4L2_STD_PAL_DK)
+					if (dev->tvnorm & V4L2_STD_PAL_BG ||
+					    dev->tvnorm & V4L2_STD_PAL_DK)
 						bpl_local = 352 << 1;
 					else
-						bpl_local =
-						 dev->channels[channel_opened].
-						 cif_width <<
-						 1;
+						bpl_local = dev->channels[
+							channel_opened].
+							cif_width << 1;
 				}
 			}
 		}
@@ -685,7 +681,7 @@
 			    struct videobuf_buffer *vb)
 {
 	struct cx25821_buffer *buf =
-	    container_of(vb, struct cx25821_buffer, vb);
+		container_of(vb, struct cx25821_buffer, vb);
 
 	cx25821_free_buffer(q, buf);
 }
@@ -723,7 +719,7 @@
 static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
 {
 	struct cx25821_buffer *buf =
-	   container_of(vb, struct cx25821_buffer, vb);
+		container_of(vb, struct cx25821_buffer, vb);
 	struct cx25821_buffer *prev;
 	struct cx25821_fh *fh = vq->priv_data;
 	struct cx25821_dev *dev = fh->dev;
@@ -814,7 +810,7 @@
 
 		for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) {
 			if (h->channels[i].video_dev &&
-			   h->channels[i].video_dev->minor == minor) {
+			    h->channels[i].video_dev->minor == minor) {
 				dev = h;
 				ch_id = i;
 				type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -848,11 +844,10 @@
 
 	v4l2_prio_open(&dev->channels[ch_id].prio, &fh->prio);
 
-	videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
-			      &dev->pci->dev, &dev->slock,
-			      V4L2_BUF_TYPE_VIDEO_CAPTURE,
-			      V4L2_FIELD_INTERLACED,
-			      sizeof(struct cx25821_buffer), fh, NULL);
+	videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops, &dev->pci->dev,
+			&dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			V4L2_FIELD_INTERLACED, sizeof(struct cx25821_buffer),
+			fh, NULL);
 
 	dprintk(1, "post videobuf_queue_init()\n");
 	mutex_unlock(&cx25821_devlist_mutex);
@@ -1168,8 +1163,8 @@
 	strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card));
 	sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
 	cap->version = CX25821_VERSION_CODE;
-	cap->capabilities =
-	    V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
+	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
+		V4L2_CAP_STREAMING;
 	if (UNSET != dev->tuner_type)
 		cap->capabilities |= V4L2_CAP_TUNER;
 	return 0;
@@ -1454,38 +1449,38 @@
 static struct v4l2_queryctrl cx25821_ctls[] = {
 	/* --- video --- */
 	{
-	 .id = V4L2_CID_BRIGHTNESS,
-	 .name = "Brightness",
-	 .minimum = 0,
-	 .maximum = 10000,
-	 .step = 1,
-	 .default_value = 6200,
-	 .type = V4L2_CTRL_TYPE_INTEGER,
-	 }, {
-	     .id = V4L2_CID_CONTRAST,
-	     .name = "Contrast",
-	     .minimum = 0,
-	     .maximum = 10000,
-	     .step = 1,
-	     .default_value = 5000,
-	     .type = V4L2_CTRL_TYPE_INTEGER,
-	     }, {
-		 .id = V4L2_CID_SATURATION,
-		 .name = "Saturation",
-		 .minimum = 0,
-		 .maximum = 10000,
-		 .step = 1,
-		 .default_value = 5000,
-		 .type = V4L2_CTRL_TYPE_INTEGER,
-		 }, {
-		     .id = V4L2_CID_HUE,
-		     .name = "Hue",
-		     .minimum = 0,
-		     .maximum = 10000,
-		     .step = 1,
-		     .default_value = 5000,
-		     .type = V4L2_CTRL_TYPE_INTEGER,
-		     }
+		.id = V4L2_CID_BRIGHTNESS,
+		.name = "Brightness",
+		.minimum = 0,
+		.maximum = 10000,
+		.step = 1,
+		.default_value = 6200,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+	}, {
+		.id = V4L2_CID_CONTRAST,
+		.name = "Contrast",
+		.minimum = 0,
+		.maximum = 10000,
+		.step = 1,
+		.default_value = 5000,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+	}, {
+		.id = V4L2_CID_SATURATION,
+		.name = "Saturation",
+		.minimum = 0,
+		.maximum = 10000,
+		.step = 1,
+		.default_value = 5000,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+	}, {
+		.id = V4L2_CID_HUE,
+		.name = "Hue",
+		.minimum = 0,
+		.maximum = 10000,
+		.step = 1,
+		.default_value = 5000,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+	}
 };
 static const int CX25821_CTLS = ARRAY_SIZE(cx25821_ctls);
 
@@ -1623,7 +1618,8 @@
 
 	if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
-	cropcap->bounds.top = cropcap->bounds.left = 0;
+	cropcap->bounds.top = 0;
+	cropcap->bounds.left = 0;
 	cropcap->bounds.width = 720;
 	cropcap->bounds.height = dev->tvnorm == V4L2_STD_PAL_BG ? 576 : 480;
 	cropcap->pixelaspect.numerator =
@@ -1829,8 +1825,11 @@
 	struct downstream_user_struct *data_from_user;
 	int command;
 	int width = 720;
-	int selected_channel = 0, pix_format = 0, i = 0;
-	int cif_enable = 0, cif_width = 0;
+	int selected_channel = 0;
+	int pix_format = 0;
+	int i = 0;
+	int cif_enable = 0;
+	int cif_width = 0;
 	u32 value = 0;
 
 	data_from_user = (struct downstream_user_struct *)arg;
@@ -1895,8 +1894,8 @@
 		}
 
 		if (selected_channel <= 7 && selected_channel >= 0) {
-			dev->channels[selected_channel].
-				use_cif_resolution = cif_enable;
+			dev->channels[selected_channel].use_cif_resolution =
+				cif_enable;
 			dev->channels[selected_channel].cif_width = width;
 		} else {
 			for (i = 0; i < VID_CHANNEL_NUM; i++) {
@@ -1932,9 +1931,9 @@
 static long cx25821_video_ioctl(struct file *file,
 				unsigned int cmd, unsigned long arg)
 {
-	int  ret = 0;
+	int ret = 0;
 
-	struct cx25821_fh  *fh  = file->private_data;
+	struct cx25821_fh *fh = file->private_data;
 
 	/* check to see if it's the video upstream */
 	if (fh->channel_id == SRAM_CH09) {
diff --git a/drivers/media/video/cx25821/cx25821.h b/drivers/media/video/cx25821/cx25821.h
index 2d2d009..b9aa801 100644
--- a/drivers/media/video/cx25821/cx25821.h
+++ b/drivers/media/video/cx25821/cx25821.h
@@ -67,7 +67,7 @@
 #define MAX_CAMERAS             16
 
 /* Max number of inputs by card */
-#define MAX_CX25821_INPUT 8
+#define MAX_CX25821_INPUT     8
 #define INPUT(nr) (&cx25821_boards[dev->board].input[nr])
 #define RESOURCE_VIDEO0       1
 #define RESOURCE_VIDEO1       2
@@ -85,7 +85,7 @@
 
 #define BUFFER_TIMEOUT     (HZ)	/* 0.5 seconds */
 
-#define UNKNOWN_BOARD       0
+#define UNKNOWN_BOARD        0
 #define CX25821_BOARD        1
 
 /* Currently supported by the driver */
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 5c42abd..3598dc0 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -70,11 +70,6 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called cx88-dvb.
 
-config VIDEO_CX88_MPEG
-	tristate
-	depends on VIDEO_CX88_DVB || VIDEO_CX88_BLACKBIRD
-	default y
-
 config VIDEO_CX88_VP3054
 	tristate "VP-3054 Secondary I2C Bus Support"
 	default m
@@ -84,3 +79,8 @@
 	  Conexant 2388x chip and the MT352 demodulator,
 	  which also require support for the VP-3054
 	  Secondary I2C bus, such at DNTV Live! DVB-T Pro.
+
+config VIDEO_CX88_MPEG
+	tristate
+	depends on VIDEO_CX88_DVB || VIDEO_CX88_BLACKBIRD
+	default y
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index a1fe0ab..de0f1af 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -132,7 +132,7 @@
 	}
 }
 
-/* init + register i2c algo-bit adapter */
+/* init + register i2c adapter */
 int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
 {
 	/* Prevents usage of invalid delay values */
diff --git a/drivers/media/video/davinci/vpbe_display.c b/drivers/media/video/davinci/vpbe_display.c
index 8588a86..d98da4b 100644
--- a/drivers/media/video/davinci/vpbe_display.c
+++ b/drivers/media/video/davinci/vpbe_display.c
@@ -1746,15 +1746,16 @@
 	for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
 		if (register_device(disp_dev->dev[i], disp_dev, pdev)) {
 			err = -ENODEV;
-			goto probe_out;
+			goto probe_out_irq;
 		}
 	}
 
 	printk(KERN_DEBUG "Successfully completed the probing of vpbe v4l2 device\n");
 	return 0;
 
-probe_out:
+probe_out_irq:
 	free_irq(res->start, disp_dev);
+probe_out:
 	for (k = 0; k < VPBE_DISPLAY_MAX_DEVICES; k++) {
 		/* Get the pointer to the layer object */
 		vpbe_display_layer = disp_dev->dev[k];
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 9b747c2..1704da0 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -336,6 +336,23 @@
 	{             -1,   -1,   -1,  -1},
 };
 
+#if 0
+static struct em28xx_reg_seq hauppauge_930c_gpio[] = {
+	{EM2874_R80_GPIO,	0x6f,	0xff,	10},
+	{EM2874_R80_GPIO,	0x4f,	0xff,	10}, /* xc5000 reset */
+	{EM2874_R80_GPIO,	0x6f,	0xff,	10},
+	{EM2874_R80_GPIO,	0x4f,	0xff,	10},
+	{ -1,			-1,	-1,	-1},
+};
+
+static struct em28xx_reg_seq hauppauge_930c_digital[] = {
+	{EM2874_R80_GPIO,	0xf6,	0xff,	10},
+	{EM2874_R80_GPIO,	0xe6,	0xff,	100},
+	{EM2874_R80_GPIO,	0xa6,	0xff,	10},
+	{ -1,			-1,	-1,	-1},
+};
+#endif
+
 /*
  *  Board definitions
  */
@@ -887,6 +904,37 @@
 		.tuner_addr   = 0x41,
 		.dvb_gpio     = terratec_h5_digital, /* FIXME: probably wrong */
 		.tuner_gpio   = terratec_h5_gpio,
+#else
+		.tuner_type   = TUNER_ABSENT,
+#endif
+		.i2c_speed    = EM2874_I2C_SECONDARY_BUS_SELECT |
+				EM28XX_I2C_CLK_WAIT_ENABLE |
+				EM28XX_I2C_FREQ_400_KHZ,
+	},
+	[EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C] = {
+		.name         = "Hauppauge WinTV HVR 930C",
+		.has_dvb      = 1,
+#if 0 /* FIXME: Add analog support */
+		.tuner_type   = TUNER_XC5000,
+		.tuner_addr   = 0x41,
+		.dvb_gpio     = hauppauge_930c_digital,
+		.tuner_gpio   = hauppauge_930c_gpio,
+#else
+		.tuner_type   = TUNER_ABSENT,
+#endif
+		.ir_codes     = RC_MAP_HAUPPAUGE,
+		.i2c_speed    = EM2874_I2C_SECONDARY_BUS_SELECT |
+				EM28XX_I2C_CLK_WAIT_ENABLE |
+				EM28XX_I2C_FREQ_400_KHZ,
+	},
+	[EM2884_BOARD_CINERGY_HTC_STICK] = {
+		.name         = "Terratec Cinergy HTC Stick",
+		.has_dvb      = 1,
+#if 0
+		.tuner_type   = TUNER_PHILIPS_TDA8290,
+		.tuner_addr   = 0x41,
+		.dvb_gpio     = terratec_h5_digital, /* FIXME: probably wrong */
+		.tuner_gpio   = terratec_h5_gpio,
 #endif
 		.i2c_speed    = EM2874_I2C_SECONDARY_BUS_SELECT |
 				EM28XX_I2C_CLK_WAIT_ENABLE |
@@ -1914,17 +1962,19 @@
 	{ USB_DEVICE(0x0ccd, 0x0042),
 			.driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS },
 	{ USB_DEVICE(0x0ccd, 0x0043),
+			.driver_info = EM2870_BOARD_TERRATEC_XS },
+	{ USB_DEVICE(0x0ccd, 0x10a2),	/* H5 Rev. 1 */
 			.driver_info = EM2884_BOARD_TERRATEC_H5 },
-	{ USB_DEVICE(0x0ccd, 0x10a2),	/* Rev. 1 */
+	{ USB_DEVICE(0x0ccd, 0x10ad),	/* H5 Rev. 2 */
 			.driver_info = EM2884_BOARD_TERRATEC_H5 },
-	{ USB_DEVICE(0x0ccd, 0x10ad),	/* Rev. 2 */
-			.driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS },
 	{ USB_DEVICE(0x0ccd, 0x0084),
 			.driver_info = EM2860_BOARD_TERRATEC_AV350 },
 	{ USB_DEVICE(0x0ccd, 0x0096),
 			.driver_info = EM2860_BOARD_TERRATEC_GRABBY },
 	{ USB_DEVICE(0x0ccd, 0x10AF),
 			.driver_info = EM2860_BOARD_TERRATEC_GRABBY },
+	{ USB_DEVICE(0x0ccd, 0x00b2),
+			.driver_info = EM2884_BOARD_CINERGY_HTC_STICK },
 	{ USB_DEVICE(0x0fd9, 0x0033),
 			.driver_info = EM2860_BOARD_ELGATO_VIDEO_CAPTURE},
 	{ USB_DEVICE(0x185b, 0x2870),
@@ -1975,6 +2025,8 @@
 			.driver_info = EM28174_BOARD_PCTV_290E },
 	{ USB_DEVICE(0x2013, 0x024c),
 			.driver_info = EM28174_BOARD_PCTV_460E },
+	{ USB_DEVICE(0x2040, 0x1605),
+			.driver_info = EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C },
 	{ },
 };
 MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -2028,10 +2080,10 @@
 	int rc = 0;
 	struct em28xx *dev = ptr;
 
-	if (dev->tuner_type != TUNER_XC2028)
+	if (dev->tuner_type != TUNER_XC2028 && dev->tuner_type != TUNER_XC5000)
 		return 0;
 
-	if (command != XC2028_TUNER_RESET)
+	if (command != XC2028_TUNER_RESET && command != XC5000_TUNER_RESET)
 		return 0;
 
 	rc = em28xx_gpio_set(dev, dev->board.tuner_gpio);
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index cef7a2d..3868c1e 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -316,6 +316,14 @@
 	.microcode_name = "dvb-usb-terratec-h5-drxk.fw",
 };
 
+struct drxk_config hauppauge_930c_drxk = {
+	.adr = 0x29,
+	.single_master = 1,
+	.no_i2c_bridge = 1,
+	.microcode_name = "dvb-usb-hauppauge-hvr930c-drxk.fw",
+	.chunk_size = 56,
+};
+
 static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
 {
 	struct em28xx_dvb *dvb = fe->sec_priv;
@@ -334,6 +342,73 @@
 	return status;
 }
 
+static void hauppauge_hvr930c_init(struct em28xx *dev)
+{
+	int i;
+
+	struct em28xx_reg_seq hauppauge_hvr930c_init[] = {
+		{EM2874_R80_GPIO,	0xff,	0xff,	0x65},
+		{EM2874_R80_GPIO,	0xfb,	0xff,	0x32},
+		{EM2874_R80_GPIO,	0xff,	0xff,	0xb8},
+		{ -1,                   -1,     -1,     -1},
+	};
+	struct em28xx_reg_seq hauppauge_hvr930c_end[] = {
+		{EM2874_R80_GPIO,	0xef,	0xff,	0x01},
+		{EM2874_R80_GPIO,	0xaf,	0xff,	0x65},
+		{EM2874_R80_GPIO,	0xef,	0xff,	0x76},
+		{EM2874_R80_GPIO,	0xef,	0xff,	0x01},
+		{EM2874_R80_GPIO,	0xcf,	0xff,	0x0b},
+		{EM2874_R80_GPIO,	0xef,	0xff,	0x40},
+
+		{EM2874_R80_GPIO,	0xcf,	0xff,	0x65},
+		{EM2874_R80_GPIO,	0xef,	0xff,	0x65},
+		{EM2874_R80_GPIO,	0xcf,	0xff,	0x0b},
+		{EM2874_R80_GPIO,	0xef,	0xff,	0x65},
+
+		{ -1,                   -1,     -1,     -1},
+	};
+
+	struct {
+		unsigned char r[4];
+		int len;
+	} regs[] = {
+		{{ 0x06, 0x02, 0x00, 0x31 }, 4},
+		{{ 0x01, 0x02 }, 2},
+		{{ 0x01, 0x02, 0x00, 0xc6 }, 4},
+		{{ 0x01, 0x00 }, 2},
+		{{ 0x01, 0x00, 0xff, 0xaf }, 4},
+		{{ 0x01, 0x00, 0x03, 0xa0 }, 4},
+		{{ 0x01, 0x00 }, 2},
+		{{ 0x01, 0x00, 0x73, 0xaf }, 4},
+		{{ 0x04, 0x00 }, 2},
+		{{ 0x00, 0x04 }, 2},
+		{{ 0x00, 0x04, 0x00, 0x0a }, 4},
+		{{ 0x04, 0x14 }, 2},
+		{{ 0x04, 0x14, 0x00, 0x00 }, 4},
+	};
+
+	em28xx_gpio_set(dev, hauppauge_hvr930c_init);
+	em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);
+	msleep(10);
+	em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44);
+	msleep(10);
+
+	dev->i2c_client.addr = 0x82 >> 1;
+
+	for (i = 0; i < ARRAY_SIZE(regs); i++)
+		i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len);
+	em28xx_gpio_set(dev, hauppauge_hvr930c_end);
+
+	msleep(100);
+
+	em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44);
+	msleep(30);
+
+	em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45);
+	msleep(10);
+
+}
+
 static void terratec_h5_init(struct em28xx *dev)
 {
 	int i;
@@ -425,13 +500,6 @@
 static struct cxd2820r_config em28xx_cxd2820r_config = {
 	.i2c_address = (0xd8 >> 1),
 	.ts_mode = CXD2820R_TS_SERIAL,
-	.if_dvbt_6  = 3300,
-	.if_dvbt_7  = 3500,
-	.if_dvbt_8  = 4000,
-	.if_dvbt2_6 = 3300,
-	.if_dvbt2_7 = 3500,
-	.if_dvbt2_8 = 4000,
-	.if_dvbc    = 5000,
 
 	/* enable LNA for DVB-T2 and DVB-C */
 	.gpio_dvbt2[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L,
@@ -788,7 +856,55 @@
 			mfe_shared = 1;
 		}
 		break;
+	case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C:
+	{
+		struct xc5000_config cfg;
+		hauppauge_hvr930c_init(dev);
+
+		dvb->dont_attach_fe1 = 1;
+
+		dvb->fe[0] = dvb_attach(drxk_attach,
+					&hauppauge_930c_drxk, &dev->i2c_adap,
+					&dvb->fe[1]);
+		if (!dvb->fe[0]) {
+			result = -EINVAL;
+			goto out_free;
+		}
+		/* FIXME: do we need a pll semaphore? */
+		dvb->fe[0]->sec_priv = dvb;
+		sema_init(&dvb->pll_mutex, 1);
+		dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl;
+		dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl;
+		dvb->fe[1]->id = 1;
+
+		/* Attach xc5000 */
+		memset(&cfg, 0, sizeof(cfg));
+		cfg.i2c_address  = 0x61;
+		cfg.if_khz = 4000;
+
+		if (dvb->fe[0]->ops.i2c_gate_ctrl)
+			dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1);
+		if (!dvb_attach(xc5000_attach, dvb->fe[0], &dev->i2c_adap,
+				&cfg)) {
+			result = -EINVAL;
+			goto out_free;
+		}
+
+		if (dvb->fe[0]->ops.i2c_gate_ctrl)
+			dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0);
+
+		/* Hack - needed by drxk/tda18271c2dd */
+		dvb->fe[1]->tuner_priv = dvb->fe[0]->tuner_priv;
+		memcpy(&dvb->fe[1]->ops.tuner_ops,
+		       &dvb->fe[0]->ops.tuner_ops,
+		       sizeof(dvb->fe[0]->ops.tuner_ops));
+
+		mfe_shared = 1;
+
+		break;
+	}
 	case EM2884_BOARD_TERRATEC_H5:
+	case EM2884_BOARD_CINERGY_HTC_STICK:
 		terratec_h5_init(dev);
 
 		dvb->dont_attach_fe1 = 1;
@@ -798,7 +914,6 @@
 			result = -EINVAL;
 			goto out_free;
 		}
-
 		/* FIXME: do we need a pll semaphore? */
 		dvb->fe[0]->sec_priv = dvb;
 		sema_init(&dvb->pll_mutex, 1);
@@ -822,6 +937,8 @@
 		       &dvb->fe[0]->ops.tuner_ops,
 		       sizeof(dvb->fe[0]->ops.tuner_ops));
 
+		mfe_shared = 1;
+
 		break;
 	case EM28174_BOARD_PCTV_460E:
 		/* attach demod */
@@ -845,6 +962,8 @@
 	}
 	/* define general-purpose callback pointer */
 	dvb->fe[0]->callback = em28xx_tuner_callback;
+	if (dvb->fe[1])
+		dvb->fe[1]->callback = em28xx_tuner_callback;
 
 	/* register everything */
 	result = em28xx_register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev);
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index 679da48..2630b26 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -306,7 +306,8 @@
 				   poll_result.rc_data[0],
 				   poll_result.toggle_bit);
 
-		if (ir->dev->chip_id == CHIP_ID_EM2874)
+		if (ir->dev->chip_id == CHIP_ID_EM2874 ||
+		    ir->dev->chip_id == CHIP_ID_EM2884)
 			/* The em2874 clears the readcount field every time the
 			   register is read.  The em2860/2880 datasheet says that it
 			   is supposed to clear the readcount, but it doesn't.  So with
@@ -371,13 +372,15 @@
 	case CHIP_ID_EM2883:
 		ir->get_key = default_polling_getkey;
 		break;
+	case CHIP_ID_EM2884:
 	case CHIP_ID_EM2874:
 	case CHIP_ID_EM28174:
 		ir->get_key = em2874_polling_getkey;
 		em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1);
 		break;
 	default:
-		printk("Unrecognized em28xx chip id: IR not supported\n");
+		printk("Unrecognized em28xx chip id 0x%02x: IR not supported\n",
+			dev->chip_id);
 		rc = -EINVAL;
 	}
 
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 2a2cb7e..b1199ef 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -38,6 +38,7 @@
 #include <media/videobuf-dvb.h>
 #endif
 #include "tuner-xc2028.h"
+#include "xc5000.h"
 #include "em28xx-reg.h"
 
 /* Boards supported by driver */
@@ -121,6 +122,8 @@
 #define EM28174_BOARD_PCTV_290E                   78
 #define EM2884_BOARD_TERRATEC_H5		  79
 #define EM28174_BOARD_PCTV_460E                   80
+#define EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C	  81
+#define EM2884_BOARD_CINERGY_HTC_STICK		  82
 
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4
diff --git a/drivers/media/video/gspca/benq.c b/drivers/media/video/gspca/benq.c
index 6ae2616..390291c 100644
--- a/drivers/media/video/gspca/benq.c
+++ b/drivers/media/video/gspca/benq.c
@@ -76,7 +76,6 @@
 	gspca_dev->cam.cam_mode = vga_mode;
 	gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
 	gspca_dev->cam.no_urb_create = 1;
-	gspca_dev->cam.reverse_alts = 1;
 	return 0;
 }
 
@@ -135,13 +134,17 @@
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
 {
+	struct usb_interface *intf;
+
 	reg_w(gspca_dev, 0x003c, 0x0003);
 	reg_w(gspca_dev, 0x003c, 0x0004);
 	reg_w(gspca_dev, 0x003c, 0x0005);
 	reg_w(gspca_dev, 0x003c, 0x0006);
 	reg_w(gspca_dev, 0x003c, 0x0007);
+
+	intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
 	usb_set_interface(gspca_dev->dev, gspca_dev->iface,
-					gspca_dev->nbalt - 1);
+					intf->num_altsetting - 1);
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c
index 2ced3b7..d74da8e 100644
--- a/drivers/media/video/gspca/gl860/gl860.c
+++ b/drivers/media/video/gspca/gl860/gl860.c
@@ -337,7 +337,6 @@
 		return -1;
 
 	cam = &gspca_dev->cam;
-	gspca_dev->nbalt = 4;
 
 	switch (sd->sensor) {
 	case ID_MI1320:
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 881e04c..271be98 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -880,7 +880,7 @@
 	for (;;) {
 		if (alt != gspca_dev->alt) {
 			alt = gspca_dev->alt;
-			if (gspca_dev->nbalt > 1) {
+			if (intf->num_altsetting > 1) {
 				ret = usb_set_interface(gspca_dev->dev,
 							gspca_dev->iface,
 							alt);
@@ -2300,7 +2300,6 @@
 	}
 	gspca_dev->dev = dev;
 	gspca_dev->iface = intf->cur_altsetting->desc.bInterfaceNumber;
-	gspca_dev->nbalt = intf->num_altsetting;
 
 	/* check if any audio device */
 	if (dev->config->desc.bNumInterfaces != 1) {
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index e444f16..5f1f46c 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -69,7 +69,6 @@
 	u8 bulk;		/* image transfer by 0:isoc / 1:bulk */
 	u8 npkt;		/* number of packets in an ISOC message
 				 * 0 is the default value: 32 packets */
-	u8 reverse_alts;	/* Alt settings are in high to low order */
 };
 
 struct gspca_dev;
@@ -208,7 +207,6 @@
 	char memory;			/* memory type (V4L2_MEMORY_xxx) */
 	__u8 iface;			/* USB interface number */
 	__u8 alt;			/* USB alternate setting */
-	__u8 nbalt;			/* number of USB alternate settings */
 	u8 audio;			/* presence of audio device */
 };
 
diff --git a/drivers/media/video/gspca/konica.c b/drivers/media/video/gspca/konica.c
index f3f7fe0..494b05e 100644
--- a/drivers/media/video/gspca/konica.c
+++ b/drivers/media/video/gspca/konica.c
@@ -247,9 +247,6 @@
 	gspca_dev->cam.cam_mode = vga_mode;
 	gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
 	gspca_dev->cam.no_urb_create = 1;
-	/* The highest alt setting has an isoc packetsize of 0, so we
-	   don't want to use it */
-	gspca_dev->nbalt--;
 
 	sd->brightness  = BRIGHTNESS_DEFAULT;
 	sd->contrast    = CONTRAST_DEFAULT;
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index ef45fa5..edd3279 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -263,7 +263,6 @@
 	cam->nmodes = ARRAY_SIZE(vga_mode);
 	cam->ctrls = sd->ctrls;
 	sd->quality = QUALITY_DEF;
-	gspca_dev->nbalt = 9;		/* use the altsetting 08 */
 	return 0;
 }
 
diff --git a/drivers/media/video/gspca/nw80x.c b/drivers/media/video/gspca/nw80x.c
index 7681814..3830054 100644
--- a/drivers/media/video/gspca/nw80x.c
+++ b/drivers/media/video/gspca/nw80x.c
@@ -1763,7 +1763,6 @@
 	if ((unsigned) webcam >= NWEBCAMS)
 		webcam = 0;
 	sd->webcam = webcam;
-	gspca_dev->cam.reverse_alts = 1;
 	gspca_dev->cam.ctrls = sd->ctrls;
 	sd->ag_cnt = -1;
 
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 6a01b35..3d68ad5 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -3348,7 +3348,6 @@
 	case BRIDGE_W9968CF:
 		cam->cam_mode = w9968cf_vga_mode;
 		cam->nmodes = ARRAY_SIZE(w9968cf_vga_mode);
-		cam->reverse_alts = 1;
 		break;
 	}
 
diff --git a/drivers/media/video/gspca/se401.c b/drivers/media/video/gspca/se401.c
index 3b71bbc..6d98353 100644
--- a/drivers/media/video/gspca/se401.c
+++ b/drivers/media/video/gspca/se401.c
@@ -376,7 +376,6 @@
 	cam->bulk_size = BULK_SIZE;
 	cam->bulk_nurbs = 4;
 	cam->ctrls = sd->ctrls;
-	gspca_dev->nbalt = 1;  /* Ignore the bogus isoc alt settings */
 	sd->resetlevel = 0x2d; /* Set initial resetlevel */
 
 	/* See if the camera supports brightness */
@@ -395,6 +394,14 @@
 	return 0;
 }
 
+/* function called at start time before URB creation */
+static int sd_isoc_init(struct gspca_dev *gspca_dev)
+{
+	gspca_dev->alt = 1;	/* Ignore the bogus isoc alt settings */
+
+	return gspca_dev->usb_err;
+}
+
 /* -- start the camera -- */
 static int sd_start(struct gspca_dev *gspca_dev)
 {
@@ -714,6 +721,7 @@
 	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
 	.init = sd_init,
+	.isoc_init = sd_isoc_init,
 	.start = sd_start,
 	.stopN = sd_stopN,
 	.dq_callback = sd_dq_callback,
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index c746bf1..c55d667 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -1235,7 +1235,7 @@
 	{DELAY, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */
 	{0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
-	{0xd1, 0x6e, 0x16, 0x50, 0x40, 0x49, 0x40, 0x10},
+	{0xd1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x40, 0x10}, /* RGBG gains */
 /*param2*/
 	{0xa1, 0x6e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
 	{0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
@@ -1779,10 +1779,6 @@
 	sd->ag_cnt = -1;
 	sd->quality = QUALITY_DEF;
 
-	/* if USB 1.1, let some bandwidth for the audio device */
-	if (gspca_dev->audio && gspca_dev->dev->speed < USB_SPEED_HIGH)
-		gspca_dev->nbalt--;
-
 	INIT_WORK(&sd->work, qual_upd);
 
 	return 0;
@@ -2063,6 +2059,16 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
+	if (sd->sensor == SENSOR_PO2030N) {
+		u8 rg1b[] =		/* red  green1 blue (no g2) */
+			{0xc1, 0x6e, 0x16, 0x00, 0x40, 0x00, 0x00, 0x10};
+
+		/* 0x40 = normal value = gain x 1 */
+		rg1b[3] = sd->ctrls[RED].val * 2;
+		rg1b[5] = sd->ctrls[BLUE].val * 2;
+		i2c_w8(gspca_dev, rg1b);
+		return;
+	}
 	reg_w1(gspca_dev, 0x05, sd->ctrls[RED].val);
 /*	reg_w1(gspca_dev, 0x07, 32); */
 	reg_w1(gspca_dev, 0x06, sd->ctrls[BLUE].val);
@@ -2397,7 +2403,7 @@
 	reg_w1(gspca_dev, 0x17, reg17);
 	reg01 &= ~S_PWR_DN;		/* sensor power on */
 	reg_w1(gspca_dev, 0x01, reg01);
-	reg01 &= ~SYS_SEL_48M;
+	reg01 &= ~SCL_SEL_OD;		/* remove open-drain mode */
 	reg_w1(gspca_dev, 0x01, reg01);
 
 	switch (sd->sensor) {
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index c82fd53..61743d4 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -451,7 +451,6 @@
 	}
 
 	cam = &gspca_dev->cam;
-	gspca_dev->nbalt = 7 + 1;	/* choose alternate 7 first */
 
 	sd->chip_revision = id->driver_info;
 	if (sd->chip_revision == Rev012A) {
diff --git a/drivers/media/video/gspca/topro.c b/drivers/media/video/gspca/topro.c
index 29596c5..acb209a 100644
--- a/drivers/media/video/gspca/topro.c
+++ b/drivers/media/video/gspca/topro.c
@@ -3946,7 +3946,7 @@
 		/* 640x480 * 30 fps does not work */
 		if (i == 6			/* if 30 fps */
 		 && gspca_dev->width == 640)
-			i = 0x86;		/* 15 fps */
+			i = 0x05;		/* 15 fps */
 	} else {
 		for (i = 0; i < ARRAY_SIZE(rates_6810) - 1; i++) {
 			if (sd->framerate >= rates_6810[i])
diff --git a/drivers/media/video/gspca/xirlink_cit.c b/drivers/media/video/gspca/xirlink_cit.c
index 3aed42a..628ba53 100644
--- a/drivers/media/video/gspca/xirlink_cit.c
+++ b/drivers/media/video/gspca/xirlink_cit.c
@@ -995,14 +995,12 @@
 	case CIT_MODEL0:
 		cam->cam_mode = model0_mode;
 		cam->nmodes = ARRAY_SIZE(model0_mode);
-		cam->reverse_alts = 1;
 		gspca_dev->ctrl_dis = ~((1 << SD_CONTRAST) | (1 << SD_HFLIP));
 		sd->sof_len = 4;
 		break;
 	case CIT_MODEL1:
 		cam->cam_mode = cif_yuv_mode;
 		cam->nmodes = ARRAY_SIZE(cif_yuv_mode);
-		cam->reverse_alts = 1;
 		gspca_dev->ctrl_dis = (1 << SD_HUE) | (1 << SD_HFLIP);
 		sd->sof_len = 4;
 		break;
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 30ea1e4..f22e02f 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -5381,12 +5381,12 @@
 	{}
 };
 
-static const struct usb_action gc0303_InitialScale[] = {
+/* from usbvm305.inf 0ac8:305b 07/06/15 (3 - tas5130c) */
+static const struct usb_action gc0303_Initial[] = {
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},		/* 00,00,01,cc, */
 	{0xa0, 0x02, ZC3XX_R008_CLOCKSETTING},		/* 00,08,02,cc, */
 	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc, */
-	{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},		/* 00,02,00,cc,
-							 * 0<->10 */
+	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},	/* 00,03,02,cc, */
 	{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},		/* 00,04,80,cc, */
 	{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},	/* 00,05,01,cc, */
@@ -5405,29 +5405,22 @@
 							 * 6<->8 */
 	{0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},		/* 00,87,10,cc, */
 	{0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR},		/* 00,8b,98,cc, */
-	{0xaa, 0x1b, 0x0024},		/* 00,1b,24,aa, */
-	{0xdd, 0x00, 0x0080},		/* 00,00,80,dd, */
-	{0xaa, 0x1b, 0x0000},		/* 00,1b,00,aa, */
-	{0xaa, 0x13, 0x0002},		/* 00,13,02,aa, */
-	{0xaa, 0x15, 0x0004},		/* 00,15,04,aa */
-/*??	{0xaa, 0x01, 0x0000}, */
 	{0xaa, 0x01, 0x0000},
 	{0xaa, 0x1a, 0x0000},		/* 00,1a,00,aa, */
 	{0xaa, 0x1c, 0x0017},		/* 00,1c,17,aa, */
+	{0xaa, 0x1b, 0x0000},
 	{0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH},		/* 00,86,82,cc, */
 	{0xa0, 0x83, ZC3XX_R087_EXPTIMEMID},		/* 00,87,83,cc, */
 	{0xa0, 0x84, ZC3XX_R088_EXPTIMELOW},		/* 00,88,84,cc, */
 	{0xaa, 0x05, 0x0010},		/* 00,05,10,aa, */
-	{0xaa, 0x0a, 0x0000},		/* 00,0a,00,aa, */
-	{0xaa, 0x0b, 0x00a0},		/* 00,0b,a0,aa, */
-	{0xaa, 0x0c, 0x0000},		/* 00,0c,00,aa, */
-	{0xaa, 0x0d, 0x00a0},		/* 00,0d,a0,aa, */
-	{0xaa, 0x0e, 0x0000},		/* 00,0e,00,aa, */
-	{0xaa, 0x0f, 0x00a0},		/* 00,0f,a0,aa, */
-	{0xaa, 0x10, 0x0000},		/* 00,10,00,aa, */
-	{0xaa, 0x11, 0x00a0},		/* 00,11,a0,aa, */
-/*??	{0xa0, 0x00, 0x0039},
-	{0xa1, 0x01, 0x0037}, */
+	{0xaa, 0x0a, 0x0002},
+	{0xaa, 0x0b, 0x0000},
+	{0xaa, 0x0c, 0x0002},
+	{0xaa, 0x0d, 0x0000},
+	{0xaa, 0x0e, 0x0002},
+	{0xaa, 0x0f, 0x0000},
+	{0xaa, 0x10, 0x0002},
+	{0xaa, 0x11, 0x0000},
 	{0xaa, 0x16, 0x0001},		/* 00,16,01,aa, */
 	{0xaa, 0x17, 0x00e8},		/* 00,17,e6,aa, (e6 -> e8) */
 	{0xaa, 0x18, 0x0002},		/* 00,18,02,aa, */
@@ -5442,17 +5435,18 @@
 	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},		/* 01,cb,13,cc, */
 	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},	/* 02,50,08,cc, */
 	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},		/* 03,01,08,cc, */
-	{0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},		/* 01,a8,60,cc, */
+	{0xa0, 0x58, ZC3XX_R1A8_DIGITALGAIN},
 	{0xa0, 0x61, ZC3XX_R116_RGAIN},			/* 01,16,61,cc, */
 	{0xa0, 0x65, ZC3XX_R118_BGAIN},			/* 01,18,65,cc */
+	{0xaa, 0x1b, 0x0000},
 	{}
 };
 
-static const struct usb_action gc0303_Initial[] = {
+static const struct usb_action gc0303_InitialScale[] = {
 	{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},		/* 00,00,01,cc, */
 	{0xa0, 0x02, ZC3XX_R008_CLOCKSETTING},		/* 00,08,02,cc, */
 	{0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},	/* 00,10,01,cc, */
-	{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},		/* 00,02,10,cc, */
+	{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
 	{0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},	/* 00,03,02,cc, */
 	{0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},		/* 00,04,80,cc, */
 	{0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},	/* 00,05,01,cc, */
@@ -5471,34 +5465,26 @@
 							 * 8<->6 */
 	{0xa0, 0x10, ZC3XX_R087_EXPTIMEMID},		/* 00,87,10,cc, */
 	{0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR},		/* 00,8b,98,cc, */
-	{0xaa, 0x1b, 0x0024},		/* 00,1b,24,aa, */
-	{0xdd, 0x00, 0x0080},		/* 00,00,80,dd, */
-	{0xaa, 0x1b, 0x0000},		/* 00,1b,00,aa, */
-	{0xaa, 0x13, 0x0002},		/* 00,13,02,aa, */
-	{0xaa, 0x15, 0x0004},		/* 00,15,04,aa */
-/*??	{0xaa, 0x01, 0x0000}, */
 	{0xaa, 0x01, 0x0000},
 	{0xaa, 0x1a, 0x0000},		/* 00,1a,00,aa, */
 	{0xaa, 0x1c, 0x0017},		/* 00,1c,17,aa, */
+	{0xaa, 0x1b, 0x0000},
 	{0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH},	/* 00,86,82,cc, */
 	{0xa0, 0x83, ZC3XX_R087_EXPTIMEMID},	/* 00,87,83,cc, */
 	{0xa0, 0x84, ZC3XX_R088_EXPTIMELOW},	/* 00,88,84,cc, */
 	{0xaa, 0x05, 0x0010},		/* 00,05,10,aa, */
-	{0xaa, 0x0a, 0x0000},		/* 00,0a,00,aa, */
-	{0xaa, 0x0b, 0x00a0},		/* 00,0b,a0,aa, */
-	{0xaa, 0x0c, 0x0000},		/* 00,0c,00,aa, */
-	{0xaa, 0x0d, 0x00a0},		/* 00,0d,a0,aa, */
-	{0xaa, 0x0e, 0x0000},		/* 00,0e,00,aa, */
-	{0xaa, 0x0f, 0x00a0},		/* 00,0f,a0,aa, */
-	{0xaa, 0x10, 0x0000},		/* 00,10,00,aa, */
-	{0xaa, 0x11, 0x00a0},		/* 00,11,a0,aa, */
-/*??	{0xa0, 0x00, 0x0039},
-	{0xa1, 0x01, 0x0037}, */
+	{0xaa, 0x0a, 0x0001},
+	{0xaa, 0x0b, 0x0000},
+	{0xaa, 0x0c, 0x0001},
+	{0xaa, 0x0d, 0x0000},
+	{0xaa, 0x0e, 0x0001},
+	{0xaa, 0x0f, 0x0000},
+	{0xaa, 0x10, 0x0001},
+	{0xaa, 0x11, 0x0000},
 	{0xaa, 0x16, 0x0001},		/* 00,16,01,aa, */
 	{0xaa, 0x17, 0x00e8},		/* 00,17,e6,aa (e6 -> e8) */
 	{0xaa, 0x18, 0x0002},		/* 00,18,02,aa, */
 	{0xaa, 0x19, 0x0088},		/* 00,19,88,aa, */
-	{0xaa, 0x20, 0x0020},		/* 00,20,20,aa, */
 	{0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION},	/* 01,01,b7,cc, */
 	{0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},	/* 00,12,05,cc, */
 	{0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},		/* 01,00,0d,cc, */
@@ -5508,36 +5494,37 @@
 	{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},		/* 01,cb,13,cc, */
 	{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},	/* 02,50,08,cc, */
 	{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},		/* 03,01,08,cc, */
-	{0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN},		/* 01,a8,60,cc, */
+	{0xa0, 0x58, ZC3XX_R1A8_DIGITALGAIN},
 	{0xa0, 0x61, ZC3XX_R116_RGAIN},		/* 01,16,61,cc, */
 	{0xa0, 0x65, ZC3XX_R118_BGAIN},		/* 01,18,65,cc */
+	{0xaa, 0x1b, 0x0000},
 	{}
 };
-static const struct usb_action gc0303_50HZScale[] = {
+static const struct usb_action gc0303_50HZ[] = {
 	{0xaa, 0x82, 0x0000},		/* 00,82,00,aa */
 	{0xaa, 0x83, 0x0001},		/* 00,83,01,aa */
-	{0xaa, 0x84, 0x00aa},		/* 00,84,aa,aa */
+	{0xaa, 0x84, 0x0063},
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},	/* 01,90,00,cc, */
 	{0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID},	/* 01,91,0d,cc, */
 	{0xa0, 0xa8, ZC3XX_R192_EXPOSURELIMITLOW},	/* 01,92,50,cc, */
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},	/* 01,95,00,cc, */
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},	/* 01,96,00,cc, */
-	{0xa0, 0x8e, ZC3XX_R197_ANTIFLICKERLOW},	/* 01,97,47,cc, */
+	{0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW},	/* 01,97,47,cc, */
 	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},		/* 01,8c,0e,cc, */
 	{0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE},		/* 01,8f,15,cc, */
 	{0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},	/* 01,a9,10,cc, */
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},	/* 01,aa,24,cc, */
+	{0xa0, 0x48, ZC3XX_R1AA_DIGITALGAINSTEP},
 	{0xa0, 0x62, ZC3XX_R01D_HSYNC_0},		/* 00,1d,62,cc, */
 	{0xa0, 0x90, ZC3XX_R01E_HSYNC_1},		/* 00,1e,90,cc, */
 	{0xa0, 0xc8, ZC3XX_R01F_HSYNC_2},		/* 00,1f,c8,cc, */
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},		/* 00,20,ff,cc, */
 	{0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN},		/* 01,1d,58,cc, */
 	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},	/* 01,80,42,cc, */
-	{0xa0, 0x78, ZC3XX_R18D_YTARGET},		/* 01,8d,78,cc */
+	{0xa0, 0x7f, ZC3XX_R18D_YTARGET},
 	{}
 };
 
-static const struct usb_action gc0303_50HZ[] = {
+static const struct usb_action gc0303_50HZScale[] = {
 	{0xaa, 0x82, 0x0000},		/* 00,82,00,aa */
 	{0xaa, 0x83, 0x0003},		/* 00,83,03,aa */
 	{0xaa, 0x84, 0x0054},		/* 00,84,54,aa */
@@ -5550,21 +5537,21 @@
 	{0xa0, 0x0e, ZC3XX_R18C_AEFREEZE},		/* 01,8c,0e,cc, */
 	{0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE},		/* 01,8f,15,cc, */
 	{0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF},	/* 01,a9,10,cc, */
-	{0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP},	/* 01,aa,24,cc, */
+	{0xa0, 0x48, ZC3XX_R1AA_DIGITALGAINSTEP},	/* 01,aa,24,cc, */
 	{0xa0, 0x62, ZC3XX_R01D_HSYNC_0},		/* 00,1d,62,cc, */
 	{0xa0, 0x90, ZC3XX_R01E_HSYNC_1},		/* 00,1e,90,cc, */
 	{0xa0, 0xc8, ZC3XX_R01F_HSYNC_2},		/* 00,1f,c8,cc, */
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},		/* 00,20,ff,cc, */
 	{0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN},		/* 01,1d,58,cc, */
 	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},	/* 01,80,42,cc, */
-	{0xa0, 0x78, ZC3XX_R18D_YTARGET},		/* 01,8d,78,cc */
+	{0xa0, 0x7f, ZC3XX_R18D_YTARGET},
 	{}
 };
 
-static const struct usb_action gc0303_60HZScale[] = {
+static const struct usb_action gc0303_60HZ[] = {
 	{0xaa, 0x82, 0x0000},		/* 00,82,00,aa */
-	{0xaa, 0x83, 0x0001},		/* 00,83,01,aa */
-	{0xaa, 0x84, 0x0062},		/* 00,84,62,aa */
+	{0xaa, 0x83, 0x0000},
+	{0xaa, 0x84, 0x003b},
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},	/* 01,90,00,cc, */
 	{0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID},	/* 01,91,05,cc, */
 	{0xa0, 0x88, ZC3XX_R192_EXPOSURELIMITLOW},	/* 01,92,88,cc, */
@@ -5581,14 +5568,14 @@
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},		/* 00,20,ff,cc, */
 	{0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN},		/* 01,1d,58,cc, */
 	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},	/* 01,80,42,cc, */
-	{0xa0, 0x78, ZC3XX_R18D_YTARGET},		/* 01,8d,78,cc */
+	{0xa0, 0x80, ZC3XX_R18D_YTARGET},
 	{}
 };
 
-static const struct usb_action gc0303_60HZ[] = {
+static const struct usb_action gc0303_60HZScale[] = {
 	{0xaa, 0x82, 0x0000},		/* 00,82,00,aa */
-	{0xaa, 0x83, 0x0002},		/* 00,83,02,aa */
-	{0xaa, 0x84, 0x00c4},		/* 00,84,c4,aa */
+	{0xaa, 0x83, 0x0000},
+	{0xaa, 0x84, 0x0076},
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},	/* 01,90,00,cc, */
 	{0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID},	/* 01,1,0b,cc, */
 	{0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW},	/* 01,2,10,cc, */
@@ -5605,18 +5592,18 @@
 	{0xa0, 0xff, ZC3XX_R020_HSYNC_3},		/* 00,0,ff,cc, */
 	{0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN},		/* 01,d,58,cc, */
 	{0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},	/* 01,80,42,cc, */
-	{0xa0, 0x78, ZC3XX_R18D_YTARGET},		/* 01,d,78,cc */
+	{0xa0, 0x80, ZC3XX_R18D_YTARGET},
 	{}
 };
 
-static const struct usb_action gc0303_NoFlikerScale[] = {
+static const struct usb_action gc0303_NoFliker[] = {
 	{0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE},		/* 01,00,0c,cc, */
 	{0xaa, 0x82, 0x0000},		/* 00,82,00,aa */
 	{0xaa, 0x83, 0x0000},		/* 00,83,00,aa */
 	{0xaa, 0x84, 0x0020},		/* 00,84,20,aa */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},	/* 01,0,00,cc, */
-	{0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID},	/* 01,91,05,cc, */
-	{0xa0, 0x88, ZC3XX_R192_EXPOSURELIMITLOW},	/* 01,92,88,cc, */
+	{0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x48, ZC3XX_R192_EXPOSURELIMITLOW},
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},	/* 01,95,00,cc, */
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},	/* 01,96,00,cc, */
 	{0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW},	/* 01,97,10,cc, */
@@ -5631,14 +5618,14 @@
 	{}
 };
 
-static const struct usb_action gc0303_NoFliker[] = {
+static const struct usb_action gc0303_NoFlikerScale[] = {
 	{0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE},		/* 01,00,0c,cc, */
 	{0xaa, 0x82, 0x0000},		/* 00,82,00,aa */
 	{0xaa, 0x83, 0x0000},		/* 00,83,00,aa */
 	{0xaa, 0x84, 0x0020},		/* 00,84,20,aa */
 	{0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},	/* 01,90,00,cc, */
-	{0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID},	/* 01,91,0b,cc, */
-	{0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW},	/* 01,92,10,cc, */
+	{0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID},
+	{0xa0, 0x48, ZC3XX_R192_EXPOSURELIMITLOW},
 	{0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},	/* 01,95,00,cc, */
 	{0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},	/* 01,96,00,cc, */
 	{0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW},	/* 01,97,10,cc, */
@@ -5809,7 +5796,7 @@
 	static const u8 tas5130c_matrix[9] =
 		{0x68, 0xec, 0xec, 0xec, 0x68, 0xec, 0xec, 0xec, 0x68};
 	static const u8 gc0303_matrix[9] =
-		{0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b};
+		{0x6c, 0xea, 0xea, 0xea, 0x6c, 0xea, 0xea, 0xea, 0x6c};
 	static const u8 *matrix_tb[SENSOR_MAX] = {
 		[SENSOR_ADCM2700] =	adcm2700_matrix,
 		[SENSOR_CS2102] =	ov7620_matrix,
@@ -6426,10 +6413,6 @@
 	gspca_dev->cam.ctrls = sd->ctrls;
 	sd->quality = QUALITY_DEF;
 
-	/* if USB 1.1, let some bandwidth for the audio device */
-	if (gspca_dev->audio && gspca_dev->dev->speed < USB_SPEED_HIGH)
-		gspca_dev->nbalt--;
-
 	return 0;
 }
 
diff --git a/drivers/media/video/ivtv/ivtv-i2c.h b/drivers/media/video/ivtv/ivtv-i2c.h
index 9332920..7b9ec1c 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.h
+++ b/drivers/media/video/ivtv/ivtv-i2c.h
@@ -25,7 +25,7 @@
 int ivtv_i2c_register(struct ivtv *itv, unsigned idx);
 struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw);
 
-/* init + register i2c algo-bit adapter */
+/* init + register i2c adapter */
 int init_ivtv_i2c(struct ivtv *itv);
 void exit_ivtv_i2c(struct ivtv *itv);
 
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index e2b1029..097c9d3 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -109,14 +109,13 @@
 
 static int reg_read(struct i2c_client *client, const u8 reg)
 {
-	s32 data = i2c_smbus_read_word_data(client, reg);
-	return data < 0 ? data : swab16(data);
+	return i2c_smbus_read_word_swapped(client, reg);
 }
 
 static int reg_write(struct i2c_client *client, const u8 reg,
 		     const u16 data)
 {
-	return i2c_smbus_write_word_data(client, reg, swab16(data));
+	return i2c_smbus_write_word_swapped(client, reg, data);
 }
 
 static int reg_set(struct i2c_client *client, const u8 reg,
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index 398f96f..95ca6c7 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -211,7 +211,7 @@
 	if (page > 2)
 		return -EINVAL;
 
-	ret = i2c_smbus_write_word_data(client, MT9M111_PAGE_MAP, swab16(page));
+	ret = i2c_smbus_write_word_swapped(client, MT9M111_PAGE_MAP, page);
 	if (!ret)
 		mt9m111->lastpage = page;
 	return ret;
@@ -223,7 +223,7 @@
 
 	ret = reg_page_map_set(client, reg);
 	if (!ret)
-		ret = swab16(i2c_smbus_read_word_data(client, reg & 0xff));
+		ret = i2c_smbus_read_word_swapped(client, reg & 0xff);
 
 	dev_dbg(&client->dev, "read  reg.%03x -> %04x\n", reg, ret);
 	return ret;
@@ -236,8 +236,7 @@
 
 	ret = reg_page_map_set(client, reg);
 	if (!ret)
-		ret = i2c_smbus_write_word_data(client, reg & 0xff,
-						swab16(data));
+		ret = i2c_smbus_write_word_swapped(client, reg & 0xff, data);
 	dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret);
 	return ret;
 }
diff --git a/drivers/media/video/mt9p031.c b/drivers/media/video/mt9p031.c
index 73c0689..93c3ec7 100644
--- a/drivers/media/video/mt9p031.c
+++ b/drivers/media/video/mt9p031.c
@@ -132,13 +132,12 @@
 
 static int mt9p031_read(struct i2c_client *client, u8 reg)
 {
-	s32 data = i2c_smbus_read_word_data(client, reg);
-	return data < 0 ? data : be16_to_cpu(data);
+	return i2c_smbus_read_word_swapped(client, reg);
 }
 
 static int mt9p031_write(struct i2c_client *client, u8 reg, u16 data)
 {
-	return i2c_smbus_write_word_data(client, reg, cpu_to_be16(data));
+	return i2c_smbus_write_word_swapped(client, reg, data);
 }
 
 static int mt9p031_set_output_control(struct mt9p031 *mt9p031, u16 clear,
diff --git a/drivers/media/video/mt9t001.c b/drivers/media/video/mt9t001.c
index 08074b8..cd81d04a 100644
--- a/drivers/media/video/mt9t001.c
+++ b/drivers/media/video/mt9t001.c
@@ -133,13 +133,12 @@
 
 static int mt9t001_read(struct i2c_client *client, u8 reg)
 {
-	s32 data = i2c_smbus_read_word_data(client, reg);
-	return data < 0 ? data : be16_to_cpu(data);
+	return i2c_smbus_read_word_swapped(client, reg);
 }
 
 static int mt9t001_write(struct i2c_client *client, u8 reg, u16 data)
 {
-	return i2c_smbus_write_word_data(client, reg, cpu_to_be16(data));
+	return i2c_smbus_write_word_swapped(client, reg, data);
 }
 
 static int mt9t001_set_output_control(struct mt9t001 *mt9t001, u16 clear,
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 0e78477..84add1a 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -90,14 +90,13 @@
 
 static int reg_read(struct i2c_client *client, const u8 reg)
 {
-	s32 data = i2c_smbus_read_word_data(client, reg);
-	return data < 0 ? data : swab16(data);
+	return i2c_smbus_read_word_swapped(client, reg);
 }
 
 static int reg_write(struct i2c_client *client, const u8 reg,
 		     const u16 data)
 {
-	return i2c_smbus_write_word_data(client, reg, swab16(data));
+	return i2c_smbus_write_word_swapped(client, reg, data);
 }
 
 static int reg_set(struct i2c_client *client, const u8 reg,
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 690ee0d..9449407 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -130,14 +130,13 @@
 
 static int reg_read(struct i2c_client *client, const u8 reg)
 {
-	s32 data = i2c_smbus_read_word_data(client, reg);
-	return data < 0 ? data : swab16(data);
+	return i2c_smbus_read_word_swapped(client, reg);
 }
 
 static int reg_write(struct i2c_client *client, const u8 reg,
 		     const u16 data)
 {
-	return i2c_smbus_write_word_data(client, reg, swab16(data));
+	return i2c_smbus_write_word_swapped(client, reg, data);
 }
 
 static int reg_set(struct i2c_client *client, const u8 reg,
diff --git a/drivers/media/video/mt9v032.c b/drivers/media/video/mt9v032.c
index f080c16..d90b982 100644
--- a/drivers/media/video/mt9v032.c
+++ b/drivers/media/video/mt9v032.c
@@ -139,10 +139,10 @@
 
 static int mt9v032_read(struct i2c_client *client, const u8 reg)
 {
-	s32 data = i2c_smbus_read_word_data(client, reg);
+	s32 data = i2c_smbus_read_word_swapped(client, reg);
 	dev_dbg(&client->dev, "%s: read 0x%04x from 0x%02x\n", __func__,
-		swab16(data), reg);
-	return data < 0 ? data : swab16(data);
+		data, reg);
+	return data;
 }
 
 static int mt9v032_write(struct i2c_client *client, const u8 reg,
@@ -150,7 +150,7 @@
 {
 	dev_dbg(&client->dev, "%s: writing 0x%04x to 0x%02x\n", __func__,
 		data, reg);
-	return i2c_smbus_write_word_data(client, reg, swab16(data));
+	return i2c_smbus_write_word_swapped(client, reg, data);
 }
 
 static int mt9v032_set_chip_control(struct mt9v032 *mt9v032, u16 clear, u16 set)
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index ee0d0b3..00d6d19 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -524,10 +524,50 @@
 	return 0;
 }
 
+static int omapvid_handle_interlace_display(struct omap_vout_device *vout,
+		unsigned int irqstatus, struct timeval timevalue)
+{
+	u32 fid;
+
+	if (vout->first_int) {
+		vout->first_int = 0;
+		goto err;
+	}
+
+	if (irqstatus & DISPC_IRQ_EVSYNC_ODD)
+		fid = 1;
+	else if (irqstatus & DISPC_IRQ_EVSYNC_EVEN)
+		fid = 0;
+	else
+		goto err;
+
+	vout->field_id ^= 1;
+	if (fid != vout->field_id) {
+		if (fid == 0)
+			vout->field_id = fid;
+	} else if (0 == fid) {
+		if (vout->cur_frm == vout->next_frm)
+			goto err;
+
+		vout->cur_frm->ts = timevalue;
+		vout->cur_frm->state = VIDEOBUF_DONE;
+		wake_up_interruptible(&vout->cur_frm->done);
+		vout->cur_frm = vout->next_frm;
+	} else {
+		if (list_empty(&vout->dma_queue) ||
+				(vout->cur_frm != vout->next_frm))
+			goto err;
+	}
+
+	return vout->field_id;
+err:
+	return 0;
+}
+
 static void omap_vout_isr(void *arg, unsigned int irqstatus)
 {
-	int ret;
-	u32 addr, fid;
+	int ret, fid, mgr_id;
+	u32 addr, irq;
 	struct omap_overlay *ovl;
 	struct timeval timevalue;
 	struct omapvideo_info *ovid;
@@ -543,112 +583,73 @@
 	if (!ovl->manager || !ovl->manager->device)
 		return;
 
+	mgr_id = ovl->manager->id;
 	cur_display = ovl->manager->device;
 
 	spin_lock(&vout->vbq_lock);
 	do_gettimeofday(&timevalue);
 
-	if (cur_display->type != OMAP_DISPLAY_TYPE_VENC) {
-		switch (cur_display->type) {
-		case OMAP_DISPLAY_TYPE_DPI:
-			if (!(irqstatus & (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2)))
-				goto vout_isr_err;
-			break;
-		case OMAP_DISPLAY_TYPE_HDMI:
-			if (!(irqstatus & DISPC_IRQ_EVSYNC_EVEN))
-				goto vout_isr_err;
-			break;
-		default:
-			goto vout_isr_err;
-		}
-		if (!vout->first_int && (vout->cur_frm != vout->next_frm)) {
-			vout->cur_frm->ts = timevalue;
-			vout->cur_frm->state = VIDEOBUF_DONE;
-			wake_up_interruptible(&vout->cur_frm->done);
-			vout->cur_frm = vout->next_frm;
-		}
-		vout->first_int = 0;
-		if (list_empty(&vout->dma_queue))
-			goto vout_isr_err;
-
-		vout->next_frm = list_entry(vout->dma_queue.next,
-				struct videobuf_buffer, queue);
-		list_del(&vout->next_frm->queue);
-
-		vout->next_frm->state = VIDEOBUF_ACTIVE;
-
-		addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i]
-			+ vout->cropped_offset;
-
-		/* First save the configuration in ovelray structure */
-		ret = omapvid_init(vout, addr);
-		if (ret)
-			printk(KERN_ERR VOUT_NAME
-				"failed to set overlay info\n");
-		/* Enable the pipeline and set the Go bit */
-		ret = omapvid_apply_changes(vout);
-		if (ret)
-			printk(KERN_ERR VOUT_NAME "failed to change mode\n");
-	} else {
-
-		if (vout->first_int) {
-			vout->first_int = 0;
-			goto vout_isr_err;
-		}
-		if (irqstatus & DISPC_IRQ_EVSYNC_ODD)
-			fid = 1;
-		else if (irqstatus & DISPC_IRQ_EVSYNC_EVEN)
-			fid = 0;
+	switch (cur_display->type) {
+	case OMAP_DISPLAY_TYPE_DSI:
+	case OMAP_DISPLAY_TYPE_DPI:
+		if (mgr_id == OMAP_DSS_CHANNEL_LCD)
+			irq = DISPC_IRQ_VSYNC;
+		else if (mgr_id == OMAP_DSS_CHANNEL_LCD2)
+			irq = DISPC_IRQ_VSYNC2;
 		else
 			goto vout_isr_err;
 
-		vout->field_id ^= 1;
-		if (fid != vout->field_id) {
-			if (0 == fid)
-				vout->field_id = fid;
-
+		if (!(irqstatus & irq))
 			goto vout_isr_err;
-		}
-		if (0 == fid) {
-			if (vout->cur_frm == vout->next_frm)
-				goto vout_isr_err;
-
-			vout->cur_frm->ts = timevalue;
-			vout->cur_frm->state = VIDEOBUF_DONE;
-			wake_up_interruptible(&vout->cur_frm->done);
-			vout->cur_frm = vout->next_frm;
-		} else if (1 == fid) {
-			if (list_empty(&vout->dma_queue) ||
-					(vout->cur_frm != vout->next_frm))
-				goto vout_isr_err;
-
-			vout->next_frm = list_entry(vout->dma_queue.next,
-					struct videobuf_buffer, queue);
-			list_del(&vout->next_frm->queue);
-
-			vout->next_frm->state = VIDEOBUF_ACTIVE;
-			addr = (unsigned long)
-				vout->queued_buf_addr[vout->next_frm->i] +
-				vout->cropped_offset;
-			/* First save the configuration in ovelray structure */
-			ret = omapvid_init(vout, addr);
-			if (ret)
-				printk(KERN_ERR VOUT_NAME
-						"failed to set overlay info\n");
-			/* Enable the pipeline and set the Go bit */
-			ret = omapvid_apply_changes(vout);
-			if (ret)
-				printk(KERN_ERR VOUT_NAME
-						"failed to change mode\n");
-		}
-
+		break;
+	case OMAP_DISPLAY_TYPE_VENC:
+		fid = omapvid_handle_interlace_display(vout, irqstatus,
+				timevalue);
+		if (!fid)
+			goto vout_isr_err;
+		break;
+	case OMAP_DISPLAY_TYPE_HDMI:
+		if (!(irqstatus & DISPC_IRQ_EVSYNC_EVEN))
+			goto vout_isr_err;
+		break;
+	default:
+		goto vout_isr_err;
 	}
 
+	if (!vout->first_int && (vout->cur_frm != vout->next_frm)) {
+		vout->cur_frm->ts = timevalue;
+		vout->cur_frm->state = VIDEOBUF_DONE;
+		wake_up_interruptible(&vout->cur_frm->done);
+		vout->cur_frm = vout->next_frm;
+	}
+
+	vout->first_int = 0;
+	if (list_empty(&vout->dma_queue))
+		goto vout_isr_err;
+
+	vout->next_frm = list_entry(vout->dma_queue.next,
+			struct videobuf_buffer, queue);
+	list_del(&vout->next_frm->queue);
+
+	vout->next_frm->state = VIDEOBUF_ACTIVE;
+
+	addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i]
+		+ vout->cropped_offset;
+
+	/* First save the configuration in ovelray structure */
+	ret = omapvid_init(vout, addr);
+	if (ret)
+		printk(KERN_ERR VOUT_NAME
+			"failed to set overlay info\n");
+	/* Enable the pipeline and set the Go bit */
+	ret = omapvid_apply_changes(vout);
+	if (ret)
+		printk(KERN_ERR VOUT_NAME "failed to change mode\n");
+
 vout_isr_err:
 	spin_unlock(&vout->vbq_lock);
 }
 
-
 /* Video buffer call backs */
 
 /*
@@ -664,10 +665,14 @@
 	u32 phy_addr = 0, virt_addr = 0;
 	struct omap_vout_device *vout = q->priv_data;
 	struct omapvideo_info *ovid = &vout->vid_info;
+	int vid_max_buf_size;
 
 	if (!vout)
 		return -EINVAL;
 
+	vid_max_buf_size = vout->vid == OMAP_VIDEO1 ? video1_bufsize :
+		video2_bufsize;
+
 	if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type)
 		return -EINVAL;
 
@@ -690,7 +695,7 @@
 		video1_numbuffers : video2_numbuffers;
 
 	/* Check the size of the buffer */
-	if (*size > vout->buffer_size) {
+	if (*size > vid_max_buf_size) {
 		v4l2_err(&vout->vid_dev->v4l2_dev,
 				"buffer allocation mismatch [%u] [%u]\n",
 				*size, vout->buffer_size);
diff --git a/drivers/media/video/omap/omap_voutdef.h b/drivers/media/video/omap/omap_voutdef.h
index d793501..27a95d2 100644
--- a/drivers/media/video/omap/omap_voutdef.h
+++ b/drivers/media/video/omap/omap_voutdef.h
@@ -25,7 +25,7 @@
 #define MAC_VRFB_CTXS	4
 #define MAX_VOUT_DEV	2
 #define MAX_OVLS	3
-#define MAX_DISPLAYS	3
+#define MAX_DISPLAYS	10
 #define MAX_MANAGERS	3
 
 #define QQVGA_WIDTH		160
diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c
index b818cac..5cc15ba 100644
--- a/drivers/media/video/omap3isp/isp.c
+++ b/drivers/media/video/omap3isp/isp.c
@@ -410,6 +410,7 @@
 static void isp_isr_sbl(struct isp_device *isp)
 {
 	struct device *dev = isp->dev;
+	struct isp_pipeline *pipe;
 	u32 sbl_pcr;
 
 	/*
@@ -423,27 +424,38 @@
 	if (sbl_pcr)
 		dev_dbg(dev, "SBL overflow (PCR = 0x%08x)\n", sbl_pcr);
 
-	if (sbl_pcr & (ISPSBL_PCR_CCDC_WBL_OVF | ISPSBL_PCR_CSIA_WBL_OVF
-		     | ISPSBL_PCR_CSIB_WBL_OVF)) {
-		isp->isp_ccdc.error = 1;
-		if (isp->isp_ccdc.output & CCDC_OUTPUT_PREVIEW)
-			isp->isp_prev.error = 1;
-		if (isp->isp_ccdc.output & CCDC_OUTPUT_RESIZER)
-			isp->isp_res.error = 1;
+	if (sbl_pcr & ISPSBL_PCR_CSIB_WBL_OVF) {
+		pipe = to_isp_pipeline(&isp->isp_ccp2.subdev.entity);
+		if (pipe != NULL)
+			pipe->error = true;
+	}
+
+	if (sbl_pcr & ISPSBL_PCR_CSIA_WBL_OVF) {
+		pipe = to_isp_pipeline(&isp->isp_csi2a.subdev.entity);
+		if (pipe != NULL)
+			pipe->error = true;
+	}
+
+	if (sbl_pcr & ISPSBL_PCR_CCDC_WBL_OVF) {
+		pipe = to_isp_pipeline(&isp->isp_ccdc.subdev.entity);
+		if (pipe != NULL)
+			pipe->error = true;
 	}
 
 	if (sbl_pcr & ISPSBL_PCR_PRV_WBL_OVF) {
-		isp->isp_prev.error = 1;
-		if (isp->isp_res.input == RESIZER_INPUT_VP &&
-		    !(isp->isp_ccdc.output & CCDC_OUTPUT_RESIZER))
-			isp->isp_res.error = 1;
+		pipe = to_isp_pipeline(&isp->isp_prev.subdev.entity);
+		if (pipe != NULL)
+			pipe->error = true;
 	}
 
 	if (sbl_pcr & (ISPSBL_PCR_RSZ1_WBL_OVF
 		       | ISPSBL_PCR_RSZ2_WBL_OVF
 		       | ISPSBL_PCR_RSZ3_WBL_OVF
-		       | ISPSBL_PCR_RSZ4_WBL_OVF))
-		isp->isp_res.error = 1;
+		       | ISPSBL_PCR_RSZ4_WBL_OVF)) {
+		pipe = to_isp_pipeline(&isp->isp_res.subdev.entity);
+		if (pipe != NULL)
+			pipe->error = true;
+	}
 
 	if (sbl_pcr & ISPSBL_PCR_H3A_AF_WBL_OVF)
 		omap3isp_stat_sbl_overflow(&isp->isp_af);
@@ -471,24 +483,17 @@
 				       IRQ0STATUS_HS_VS_IRQ;
 	struct isp_device *isp = _isp;
 	u32 irqstatus;
-	int ret;
 
 	irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
 	isp_reg_writel(isp, irqstatus, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
 
 	isp_isr_sbl(isp);
 
-	if (irqstatus & IRQ0STATUS_CSIA_IRQ) {
-		ret = omap3isp_csi2_isr(&isp->isp_csi2a);
-		if (ret)
-			isp->isp_ccdc.error = 1;
-	}
+	if (irqstatus & IRQ0STATUS_CSIA_IRQ)
+		omap3isp_csi2_isr(&isp->isp_csi2a);
 
-	if (irqstatus & IRQ0STATUS_CSIB_IRQ) {
-		ret = omap3isp_ccp2_isr(&isp->isp_ccp2);
-		if (ret)
-			isp->isp_ccdc.error = 1;
-	}
+	if (irqstatus & IRQ0STATUS_CSIB_IRQ)
+		omap3isp_ccp2_isr(&isp->isp_ccp2);
 
 	if (irqstatus & IRQ0STATUS_CCDC_VD0_IRQ) {
 		if (isp->isp_ccdc.output & CCDC_OUTPUT_PREVIEW)
diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c
index 54a4a3f..3663834 100644
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ b/drivers/media/video/omap3isp/ispccdc.c
@@ -1406,9 +1406,8 @@
 
 static void ccdc_hs_vs_isr(struct isp_ccdc_device *ccdc)
 {
-	struct isp_pipeline *pipe =
-		to_isp_pipeline(&ccdc->video_out.video.entity);
-	struct video_device *vdev = ccdc->subdev.devnode;
+	struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
+	struct video_device *vdev = &ccdc->subdev.devnode;
 	struct v4l2_event event;
 
 	memset(&event, 0, sizeof(event));
@@ -1428,8 +1427,11 @@
 	unsigned long flags;
 
 	if (events & IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ) {
+		struct isp_pipeline *pipe =
+			to_isp_pipeline(&ccdc->subdev.entity);
+
 		ccdc_lsc_error_handler(ccdc);
-		ccdc->error = 1;
+		pipe->error = true;
 		dev_dbg(to_device(ccdc), "lsc prefetch error\n");
 	}
 
@@ -1504,7 +1506,7 @@
 		goto done;
 	}
 
-	buffer = omap3isp_video_buffer_next(&ccdc->video_out, ccdc->error);
+	buffer = omap3isp_video_buffer_next(&ccdc->video_out);
 	if (buffer != NULL) {
 		ccdc_set_outaddr(ccdc, buffer->isp_addr);
 		restart = 1;
@@ -1518,7 +1520,6 @@
 					ISP_PIPELINE_STREAM_SINGLESHOT);
 
 done:
-	ccdc->error = 0;
 	return restart;
 }
 
@@ -1744,7 +1745,6 @@
 		 */
 		ccdc_config_vp(ccdc);
 		ccdc_enable_vp(ccdc, 1);
-		ccdc->error = 0;
 		ccdc_print_status(ccdc);
 	}
 
diff --git a/drivers/media/video/omap3isp/ispccdc.h b/drivers/media/video/omap3isp/ispccdc.h
index 483a19c..6d0264b 100644
--- a/drivers/media/video/omap3isp/ispccdc.h
+++ b/drivers/media/video/omap3isp/ispccdc.h
@@ -150,7 +150,6 @@
  * @input: Active input
  * @output: Active outputs
  * @video_out: Output video node
- * @error: A hardware error occurred during capture
  * @alaw: A-law compression enabled (1) or disabled (0)
  * @lpf: Low pass filter enabled (1) or disabled (0)
  * @obclamp: Optical-black clamp enabled (1) or disabled (0)
@@ -178,7 +177,6 @@
 	enum ccdc_input_entity input;
 	unsigned int output;
 	struct isp_video video_out;
-	unsigned int error;
 
 	unsigned int alaw:1,
 		     lpf:1,
diff --git a/drivers/media/video/omap3isp/ispccp2.c b/drivers/media/video/omap3isp/ispccp2.c
index 904ca8c..70ddbf3 100644
--- a/drivers/media/video/omap3isp/ispccp2.c
+++ b/drivers/media/video/omap3isp/ispccp2.c
@@ -556,7 +556,7 @@
 	struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
 	struct isp_buffer *buffer;
 
-	buffer = omap3isp_video_buffer_next(&ccp2->video_in, ccp2->error);
+	buffer = omap3isp_video_buffer_next(&ccp2->video_in);
 	if (buffer != NULL)
 		ccp2_set_inaddr(ccp2, buffer->isp_addr);
 
@@ -567,8 +567,6 @@
 			omap3isp_pipeline_set_stream(pipe,
 						ISP_PIPELINE_STREAM_SINGLESHOT);
 	}
-
-	ccp2->error = 0;
 }
 
 /*
@@ -576,13 +574,11 @@
  * @ccp2: Pointer to ISP CCP2 device
  *
  * This will handle the CCP2 interrupts
- *
- * Returns -EIO in case of error, or 0 on success.
  */
-int omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2)
+void omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2)
 {
+	struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
 	struct isp_device *isp = to_isp_device(ccp2);
-	int ret = 0;
 	static const u32 ISPCCP2_LC01_ERROR =
 		ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ |
 		ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ |
@@ -604,19 +600,18 @@
 		       ISPCCP2_LCM_IRQSTATUS);
 	/* Errors */
 	if (lcx_irqstatus & ISPCCP2_LC01_ERROR) {
-		ccp2->error = 1;
+		pipe->error = true;
 		dev_dbg(isp->dev, "CCP2 err:%x\n", lcx_irqstatus);
-		return -EIO;
+		return;
 	}
 
 	if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ) {
-		ccp2->error = 1;
+		pipe->error = true;
 		dev_dbg(isp->dev, "CCP2 OCP err:%x\n", lcm_irqstatus);
-		ret = -EIO;
 	}
 
 	if (omap3isp_module_sync_is_stopping(&ccp2->wait, &ccp2->stopping))
-		return 0;
+		return;
 
 	/* Frame number propagation */
 	if (lcx_irqstatus & ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ) {
@@ -629,8 +624,6 @@
 	/* Handle queued buffers on frame end interrupts */
 	if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_EOF_IRQ)
 		ccp2_isr_buffer(ccp2);
-
-	return ret;
 }
 
 /* -----------------------------------------------------------------------------
@@ -867,7 +860,6 @@
 		if (enable == ISP_PIPELINE_STREAM_STOPPED)
 			return 0;
 		atomic_set(&ccp2->stopping, 0);
-		ccp2->error = 0;
 	}
 
 	switch (enable) {
diff --git a/drivers/media/video/omap3isp/ispccp2.h b/drivers/media/video/omap3isp/ispccp2.h
index 6674e9d..76d65f4 100644
--- a/drivers/media/video/omap3isp/ispccp2.h
+++ b/drivers/media/video/omap3isp/ispccp2.h
@@ -82,7 +82,6 @@
 	struct isp_video video_in;
 	struct isp_csiphy *phy;
 	struct regulator *vdds_csib;
-	unsigned int error;
 	enum isp_pipeline_stream_state state;
 	wait_queue_head_t wait;
 	atomic_t stopping;
@@ -94,6 +93,6 @@
 int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2,
 			struct v4l2_device *vdev);
 void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2);
-int omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2);
+void omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2);
 
 #endif	/* OMAP3_ISP_CCP2_H */
diff --git a/drivers/media/video/omap3isp/ispcsi2.c b/drivers/media/video/omap3isp/ispcsi2.c
index 0c5f1cb..fcb5168 100644
--- a/drivers/media/video/omap3isp/ispcsi2.c
+++ b/drivers/media/video/omap3isp/ispcsi2.c
@@ -667,7 +667,7 @@
 
 	csi2_ctx_enable(isp, csi2, 0, 0);
 
-	buffer = omap3isp_video_buffer_next(&csi2->video_out, 0);
+	buffer = omap3isp_video_buffer_next(&csi2->video_out);
 
 	/*
 	 * Let video queue operation restart engine if there is an underrun
@@ -727,17 +727,15 @@
 
 /*
  * omap3isp_csi2_isr - CSI2 interrupt handling.
- *
- * Return -EIO on Transmission error
  */
-int omap3isp_csi2_isr(struct isp_csi2_device *csi2)
+void omap3isp_csi2_isr(struct isp_csi2_device *csi2)
 {
+	struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity);
 	u32 csi2_irqstatus, cpxio1_irqstatus;
 	struct isp_device *isp = csi2->isp;
-	int retval = 0;
 
 	if (!csi2->available)
-		return -ENODEV;
+		return;
 
 	csi2_irqstatus = isp_reg_readl(isp, csi2->regs1, ISPCSI2_IRQSTATUS);
 	isp_reg_writel(isp, csi2_irqstatus, csi2->regs1, ISPCSI2_IRQSTATUS);
@@ -750,7 +748,7 @@
 			       csi2->regs1, ISPCSI2_PHY_IRQSTATUS);
 		dev_dbg(isp->dev, "CSI2: ComplexIO Error IRQ "
 			"%x\n", cpxio1_irqstatus);
-		retval = -EIO;
+		pipe->error = true;
 	}
 
 	if (csi2_irqstatus & (ISPCSI2_IRQSTATUS_OCP_ERR_IRQ |
@@ -775,11 +773,11 @@
 			 ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ) ? 1 : 0,
 			(csi2_irqstatus &
 			 ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ) ? 1 : 0);
-		retval = -EIO;
+		pipe->error = true;
 	}
 
 	if (omap3isp_module_sync_is_stopping(&csi2->wait, &csi2->stopping))
-		return 0;
+		return;
 
 	/* Successful cases */
 	if (csi2_irqstatus & ISPCSI2_IRQSTATUS_CONTEXT(0))
@@ -787,8 +785,6 @@
 
 	if (csi2_irqstatus & ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ)
 		dev_dbg(isp->dev, "CSI2: ECC correction done\n");
-
-	return retval;
 }
 
 /* -----------------------------------------------------------------------------
diff --git a/drivers/media/video/omap3isp/ispcsi2.h b/drivers/media/video/omap3isp/ispcsi2.h
index 456fb7f..885ad79 100644
--- a/drivers/media/video/omap3isp/ispcsi2.h
+++ b/drivers/media/video/omap3isp/ispcsi2.h
@@ -156,7 +156,7 @@
 	atomic_t stopping;
 };
 
-int omap3isp_csi2_isr(struct isp_csi2_device *csi2);
+void omap3isp_csi2_isr(struct isp_csi2_device *csi2);
 int omap3isp_csi2_reset(struct isp_csi2_device *csi2);
 int omap3isp_csi2_init(struct isp_device *isp);
 void omap3isp_csi2_cleanup(struct isp_device *isp);
diff --git a/drivers/media/video/omap3isp/isppreview.c b/drivers/media/video/omap3isp/isppreview.c
index ccb876f..6d0fb2c 100644
--- a/drivers/media/video/omap3isp/isppreview.c
+++ b/drivers/media/video/omap3isp/isppreview.c
@@ -116,11 +116,11 @@
 #define PREV_MIN_IN_HEIGHT	8
 #define PREV_MAX_IN_HEIGHT	16384
 
-#define PREV_MIN_OUT_WIDTH	0
-#define PREV_MIN_OUT_HEIGHT	0
-#define PREV_MAX_OUT_WIDTH	1280
-#define PREV_MAX_OUT_WIDTH_ES2	3300
-#define PREV_MAX_OUT_WIDTH_3630	4096
+#define PREV_MIN_OUT_WIDTH		0
+#define PREV_MIN_OUT_HEIGHT		0
+#define PREV_MAX_OUT_WIDTH_REV_1	1280
+#define PREV_MAX_OUT_WIDTH_REV_2	3300
+#define PREV_MAX_OUT_WIDTH_REV_15	4096
 
 /*
  * Coeficient Tables for the submodules in Preview.
@@ -1306,14 +1306,14 @@
 
 	switch (isp->revision) {
 	case ISP_REVISION_1_0:
-		return PREV_MAX_OUT_WIDTH;
+		return PREV_MAX_OUT_WIDTH_REV_1;
 
 	case ISP_REVISION_2_0:
 	default:
-		return PREV_MAX_OUT_WIDTH_ES2;
+		return PREV_MAX_OUT_WIDTH_REV_2;
 
 	case ISP_REVISION_15_0:
-		return PREV_MAX_OUT_WIDTH_3630;
+		return PREV_MAX_OUT_WIDTH_REV_15;
 	}
 }
 
@@ -1404,16 +1404,14 @@
 	int restart = 0;
 
 	if (prev->input == PREVIEW_INPUT_MEMORY) {
-		buffer = omap3isp_video_buffer_next(&prev->video_in,
-						    prev->error);
+		buffer = omap3isp_video_buffer_next(&prev->video_in);
 		if (buffer != NULL)
 			preview_set_inaddr(prev, buffer->isp_addr);
 		pipe->state |= ISP_PIPELINE_IDLE_INPUT;
 	}
 
 	if (prev->output & PREVIEW_OUTPUT_MEMORY) {
-		buffer = omap3isp_video_buffer_next(&prev->video_out,
-						    prev->error);
+		buffer = omap3isp_video_buffer_next(&prev->video_out);
 		if (buffer != NULL) {
 			preview_set_outaddr(prev, buffer->isp_addr);
 			restart = 1;
@@ -1440,8 +1438,6 @@
 	default:
 		return;
 	}
-
-	prev->error = 0;
 }
 
 /*
@@ -1565,7 +1561,6 @@
 		omap3isp_subclk_enable(isp, OMAP3_ISP_SUBCLK_PREVIEW);
 		preview_configure(prev);
 		atomic_set(&prev->stopping, 0);
-		prev->error = 0;
 		preview_print_status(prev);
 	}
 
diff --git a/drivers/media/video/omap3isp/isppreview.h b/drivers/media/video/omap3isp/isppreview.h
index f54e775..0968660 100644
--- a/drivers/media/video/omap3isp/isppreview.h
+++ b/drivers/media/video/omap3isp/isppreview.h
@@ -157,7 +157,6 @@
  * @output: Bitmask of the active output
  * @video_in: Input video entity
  * @video_out: Output video entity
- * @error: A hardware error occurred during capture
  * @params: Module configuration data
  * @shadow_update: If set, update the hardware configured in the next interrupt
  * @underrun: Whether the preview entity has queued buffers on the output
@@ -179,7 +178,6 @@
 	unsigned int output;
 	struct isp_video video_in;
 	struct isp_video video_out;
-	unsigned int error;
 
 	struct prev_params params;
 	unsigned int shadow_update:1;
diff --git a/drivers/media/video/omap3isp/ispresizer.c b/drivers/media/video/omap3isp/ispresizer.c
index 50e593b..6958a9e 100644
--- a/drivers/media/video/omap3isp/ispresizer.c
+++ b/drivers/media/video/omap3isp/ispresizer.c
@@ -1038,7 +1038,7 @@
 	/* Complete the output buffer and, if reading from memory, the input
 	 * buffer.
 	 */
-	buffer = omap3isp_video_buffer_next(&res->video_out, res->error);
+	buffer = omap3isp_video_buffer_next(&res->video_out);
 	if (buffer != NULL) {
 		resizer_set_outaddr(res, buffer->isp_addr);
 		restart = 1;
@@ -1047,7 +1047,7 @@
 	pipe->state |= ISP_PIPELINE_IDLE_OUTPUT;
 
 	if (res->input == RESIZER_INPUT_MEMORY) {
-		buffer = omap3isp_video_buffer_next(&res->video_in, 0);
+		buffer = omap3isp_video_buffer_next(&res->video_in);
 		if (buffer != NULL)
 			resizer_set_inaddr(res, buffer->isp_addr);
 		pipe->state |= ISP_PIPELINE_IDLE_INPUT;
@@ -1064,8 +1064,6 @@
 		if (restart)
 			resizer_enable_oneshot(res);
 	}
-
-	res->error = 0;
 }
 
 /*
@@ -1154,7 +1152,6 @@
 
 		omap3isp_subclk_enable(isp, OMAP3_ISP_SUBCLK_RESIZER);
 		resizer_configure(res);
-		res->error = 0;
 		resizer_print_status(res);
 	}
 
diff --git a/drivers/media/video/omap3isp/ispresizer.h b/drivers/media/video/omap3isp/ispresizer.h
index 76abc2e..70c1c0e 100644
--- a/drivers/media/video/omap3isp/ispresizer.h
+++ b/drivers/media/video/omap3isp/ispresizer.h
@@ -107,7 +107,6 @@
 	enum resizer_input_entity input;
 	struct isp_video video_in;
 	struct isp_video video_out;
-	unsigned int error;
 
 	u32 addr_base;   /* stored source buffer address in memory mode */
 	u32 crop_offset; /* additional offset for crop in memory mode */
diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c
index f229057..615dae5 100644
--- a/drivers/media/video/omap3isp/ispvideo.c
+++ b/drivers/media/video/omap3isp/ispvideo.c
@@ -211,14 +211,14 @@
 	mbus->width = pix->width;
 	mbus->height = pix->height;
 
-	for (i = 0; i < ARRAY_SIZE(formats); ++i) {
+	/* Skip the last format in the loop so that it will be selected if no
+	 * match is found.
+	 */
+	for (i = 0; i < ARRAY_SIZE(formats) - 1; ++i) {
 		if (formats[i].pixelformat == pix->pixelformat)
 			break;
 	}
 
-	if (WARN_ON(i == ARRAY_SIZE(formats)))
-		return;
-
 	mbus->code = formats[i].code;
 	mbus->colorspace = pix->colorspace;
 	mbus->field = pix->field;
@@ -581,21 +581,20 @@
 /*
  * omap3isp_video_buffer_next - Complete the current buffer and return the next
  * @video: ISP video object
- * @error: Whether an error occurred during capture
  *
  * Remove the current video buffer from the DMA queue and fill its timestamp,
  * field count and state fields before waking up its completion handler.
  *
- * The buffer state is set to VIDEOBUF_DONE if no error occurred (@error is 0)
- * or VIDEOBUF_ERROR otherwise (@error is non-zero).
+ * For capture video nodes the buffer state is set to ISP_BUF_STATE_DONE if no
+ * error has been flagged in the pipeline, or to ISP_BUF_STATE_ERROR otherwise.
+ * For video output nodes the buffer state is always set to ISP_BUF_STATE_DONE.
  *
  * The DMA queue is expected to contain at least one buffer.
  *
  * Return a pointer to the next buffer in the DMA queue, or NULL if the queue is
  * empty.
  */
-struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video,
-					      unsigned int error)
+struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
 {
 	struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
 	struct isp_video_queue *queue = video->queue;
@@ -630,7 +629,13 @@
 	else
 		buf->vbuf.sequence = atomic_read(&pipe->frame_number);
 
-	buf->state = error ? ISP_BUF_STATE_ERROR : ISP_BUF_STATE_DONE;
+	/* Report pipeline errors to userspace on the capture device side. */
+	if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pipe->error) {
+		buf->state = ISP_BUF_STATE_ERROR;
+		pipe->error = false;
+	} else {
+		buf->state = ISP_BUF_STATE_DONE;
+	}
 
 	wake_up(&buf->wait);
 
@@ -1016,6 +1021,8 @@
 	if (ret < 0)
 		goto error;
 
+	pipe->error = false;
+
 	spin_lock_irqsave(&pipe->lock, flags);
 	pipe->state &= ~ISP_PIPELINE_STREAM;
 	pipe->state |= state;
diff --git a/drivers/media/video/omap3isp/ispvideo.h b/drivers/media/video/omap3isp/ispvideo.h
index 08cbfa1..d91bdb9 100644
--- a/drivers/media/video/omap3isp/ispvideo.h
+++ b/drivers/media/video/omap3isp/ispvideo.h
@@ -85,6 +85,10 @@
 	ISP_PIPELINE_STREAM = 64,
 };
 
+/*
+ * struct isp_pipeline - An ISP hardware pipeline
+ * @error: A hardware error occurred during capture
+ */
 struct isp_pipeline {
 	struct media_pipeline pipe;
 	spinlock_t lock;		/* Pipeline state and queue flags */
@@ -96,6 +100,7 @@
 	unsigned int max_rate;
 	atomic_t frame_number;
 	bool do_propagation; /* of frame number */
+	bool error;
 	struct v4l2_fract max_timeperframe;
 };
 
@@ -194,8 +199,7 @@
 int omap3isp_video_register(struct isp_video *video,
 			    struct v4l2_device *vdev);
 void omap3isp_video_unregister(struct isp_video *video);
-struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video,
-					      unsigned int error);
+struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video);
 void omap3isp_video_resume(struct isp_video *video, int continuous);
 struct media_pad *omap3isp_video_remote_pad(struct isp_video *video);
 
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 122b457..ebc2c7e 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -2546,8 +2546,9 @@
 	}
 
 	/* Define and configure additional controls from cx2341x module. */
-	hdw->mpeg_ctrl_info = kzalloc(
-		sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL);
+	hdw->mpeg_ctrl_info = kcalloc(MPEGDEF_COUNT,
+				      sizeof(*(hdw->mpeg_ctrl_info)),
+				      GFP_KERNEL);
 	if (!hdw->mpeg_ctrl_info) goto fail;
 	for (idx = 0; idx < MPEGDEF_COUNT; idx++) {
 		cptr = hdw->controls + idx + CTRLDEF_COUNT;
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
index 3977add..b42c239 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -113,10 +113,9 @@
 	void *kbuf = NULL;
 
 	if (buflen) {
-		kbuf = kmalloc(buflen, GFP_KERNEL); /* not allowed on stack */
+		kbuf = kmemdup(buf, buflen, GFP_KERNEL); /* not allowed on stack */
 		if (kbuf == NULL)
 			return -ENOMEM;
-		memcpy(kbuf, buf, buflen);
 	}
 
 	rc = usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
diff --git a/drivers/media/video/s5p-g2d/Makefile b/drivers/media/video/s5p-g2d/Makefile
new file mode 100644
index 0000000..2c48c41
--- /dev/null
+++ b/drivers/media/video/s5p-g2d/Makefile
@@ -0,0 +1,3 @@
+s5p-g2d-objs := g2d.o g2d-hw.o
+
+obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D)	+= s5p-g2d.o
diff --git a/drivers/media/video/s5p-g2d/g2d-hw.c b/drivers/media/video/s5p-g2d/g2d-hw.c
new file mode 100644
index 0000000..39937cf
--- /dev/null
+++ b/drivers/media/video/s5p-g2d/g2d-hw.c
@@ -0,0 +1,104 @@
+/*
+ * Samsung S5P G2D - 2D Graphics Accelerator Driver
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * Kamil Debski, <k.debski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version
+ */
+
+#include <linux/io.h>
+
+#include "g2d.h"
+#include "g2d-regs.h"
+
+#define w(x, a)	writel((x), d->regs + (a))
+#define r(a)	readl(d->regs + (a))
+
+/* g2d_reset clears all g2d registers */
+void g2d_reset(struct g2d_dev *d)
+{
+	w(1, SOFT_RESET_REG);
+}
+
+void g2d_set_src_size(struct g2d_dev *d, struct g2d_frame *f)
+{
+	u32 n;
+
+	w(f->stride & 0xFFFF, SRC_STRIDE_REG);
+
+	n = f->o_height & 0xFFF;
+	n <<= 16;
+	n |= f->o_width & 0xFFF;
+	w(n, SRC_LEFT_TOP_REG);
+
+	n = f->bottom & 0xFFF;
+	n <<= 16;
+	n |= f->right & 0xFFF;
+	w(n, SRC_RIGHT_BOTTOM_REG);
+
+	w(f->fmt->hw, SRC_COLOR_MODE_REG);
+}
+
+void g2d_set_src_addr(struct g2d_dev *d, dma_addr_t a)
+{
+	w(a, SRC_BASE_ADDR_REG);
+}
+
+void g2d_set_dst_size(struct g2d_dev *d, struct g2d_frame *f)
+{
+	u32 n;
+
+	w(f->stride & 0xFFFF, DST_STRIDE_REG);
+
+	n = f->o_height & 0xFFF;
+	n <<= 16;
+	n |= f->o_width & 0xFFF;
+	w(n, DST_LEFT_TOP_REG);
+
+	n = f->bottom & 0xFFF;
+	n <<= 16;
+	n |= f->right & 0xFFF;
+	w(n, DST_RIGHT_BOTTOM_REG);
+
+	w(f->fmt->hw, DST_COLOR_MODE_REG);
+}
+
+void g2d_set_dst_addr(struct g2d_dev *d, dma_addr_t a)
+{
+	w(a, DST_BASE_ADDR_REG);
+}
+
+void g2d_set_rop4(struct g2d_dev *d, u32 r)
+{
+	w(r, ROP4_REG);
+}
+
+u32 g2d_cmd_stretch(u32 e)
+{
+	e &= 1;
+	return e << 4;
+}
+
+void g2d_set_cmd(struct g2d_dev *d, u32 c)
+{
+	w(c, BITBLT_COMMAND_REG);
+}
+
+void g2d_start(struct g2d_dev *d)
+{
+	/* Clear cache */
+	w(0x7, CACHECTL_REG);
+	/* Enable interrupt */
+	w(1, INTEN_REG);
+	/* Start G2D engine */
+	w(1, BITBLT_START_REG);
+}
+
+void g2d_clear_int(struct g2d_dev *d)
+{
+	w(1, INTC_PEND_REG);
+}
diff --git a/drivers/media/video/s5p-g2d/g2d-regs.h b/drivers/media/video/s5p-g2d/g2d-regs.h
new file mode 100644
index 0000000..02e1cf5
--- /dev/null
+++ b/drivers/media/video/s5p-g2d/g2d-regs.h
@@ -0,0 +1,115 @@
+/*
+ * Samsung S5P G2D - 2D Graphics Accelerator Driver
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * Kamil Debski, <k.debski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version
+ */
+
+/* General Registers */
+#define SOFT_RESET_REG		0x0000	/* Software reset reg */
+#define INTEN_REG		0x0004	/* Interrupt Enable reg */
+#define INTC_PEND_REG		0x000C	/* Interrupt Control Pending reg */
+#define FIFO_STAT_REG		0x0010	/* Command FIFO Status reg */
+#define AXI_ID_MODE_REG		0x0014	/* AXI Read ID Mode reg */
+#define CACHECTL_REG		0x0018	/* Cache & Buffer clear reg */
+#define AXI_MODE_REG		0x001C	/* AXI Mode reg */
+
+/* Command Registers */
+#define BITBLT_START_REG	0x0100	/* BitBLT Start reg */
+#define BITBLT_COMMAND_REG	0x0104	/* Command reg for BitBLT */
+
+/* Parameter Setting Registers (Rotate & Direction) */
+#define ROTATE_REG		0x0200	/* Rotation reg */
+#define SRC_MSK_DIRECT_REG	0x0204	/* Src and Mask Direction reg */
+#define DST_PAT_DIRECT_REG	0x0208	/* Dest and Pattern Direction reg */
+
+/* Parameter Setting Registers (Src) */
+#define SRC_SELECT_REG		0x0300	/* Src Image Selection reg */
+#define SRC_BASE_ADDR_REG	0x0304	/* Src Image Base Address reg */
+#define SRC_STRIDE_REG		0x0308	/* Src Stride reg */
+#define SRC_COLOR_MODE_REG	0x030C	/* Src Image Color Mode reg */
+#define SRC_LEFT_TOP_REG	0x0310	/* Src Left Top Coordinate reg */
+#define SRC_RIGHT_BOTTOM_REG	0x0314	/* Src Right Bottom Coordinate reg */
+
+/* Parameter Setting Registers (Dest) */
+#define DST_SELECT_REG		0x0400	/* Dest Image Selection reg */
+#define DST_BASE_ADDR_REG	0x0404	/* Dest Image Base Address reg */
+#define DST_STRIDE_REG		0x0408	/* Dest Stride reg */
+#define DST_COLOR_MODE_REG	0x040C	/* Dest Image Color Mode reg */
+#define DST_LEFT_TOP_REG	0x0410	/* Dest Left Top Coordinate reg */
+#define DST_RIGHT_BOTTOM_REG	0x0414	/* Dest Right Bottom Coordinate reg */
+
+/* Parameter Setting Registers (Pattern) */
+#define PAT_BASE_ADDR_REG	0x0500	/* Pattern Image Base Address reg */
+#define PAT_SIZE_REG		0x0504	/* Pattern Image Size reg */
+#define PAT_COLOR_MODE_REG	0x0508	/* Pattern Image Color Mode reg */
+#define PAT_OFFSET_REG		0x050C	/* Pattern Left Top Coordinate reg */
+#define PAT_STRIDE_REG		0x0510	/* Pattern Stride reg */
+
+/* Parameter Setting Registers (Mask) */
+#define MASK_BASE_ADDR_REG	0x0520	/* Mask Base Address reg */
+#define MASK_STRIDE_REG		0x0524	/* Mask Stride reg */
+
+/* Parameter Setting Registers (Clipping Window) */
+#define CW_LT_REG		0x0600	/* LeftTop coordinates of Clip Window */
+#define CW_RB_REG		0x0604	/* RightBottom coordinates of Clip
+								Window */
+
+/* Parameter Setting Registers (ROP & Alpha Setting) */
+#define THIRD_OPERAND_REG	0x0610	/* Third Operand Selection reg */
+#define ROP4_REG		0x0614	/* Raster Operation reg */
+#define ALPHA_REG		0x0618	/* Alpha value, Fading offset value */
+
+/* Parameter Setting Registers (Color) */
+#define FG_COLOR_REG		0x0700	/* Foreground Color reg */
+#define BG_COLOR_REG		0x0704	/* Background Color reg */
+#define BS_COLOR_REG		0x0708	/* Blue Screen Color reg */
+
+/* Parameter Setting Registers (Color Key) */
+#define SRC_COLORKEY_CTRL_REG	0x0710	/* Src Colorkey control reg */
+#define SRC_COLORKEY_DR_MIN_REG	0x0714	/* Src Colorkey Decision Reference
+								Min reg */
+#define SRC_COLORKEY_DR_MAX_REG	0x0718	/* Src Colorkey Decision Reference
+								Max reg */
+#define DST_COLORKEY_CTRL_REG	0x071C	/* Dest Colorkey control reg */
+#define DST_COLORKEY_DR_MIN_REG	0x0720	/* Dest Colorkey Decision Reference
+								Min reg */
+#define DST_COLORKEY_DR_MAX_REG	0x0724	/* Dest Colorkey Decision Reference
+								Max reg */
+
+/* Color mode values */
+
+#define ORDER_XRGB		0
+#define ORDER_RGBX		1
+#define ORDER_XBGR		2
+#define ORDER_BGRX		3
+
+#define MODE_XRGB_8888		0
+#define MODE_ARGB_8888		1
+#define MODE_RGB_565		2
+#define MODE_XRGB_1555		3
+#define MODE_ARGB_1555		4
+#define MODE_XRGB_4444		5
+#define MODE_ARGB_4444		6
+#define MODE_PACKED_RGB_888	7
+
+#define COLOR_MODE(o, m)	(((o) << 4) | (m))
+
+/* ROP4 operation values */
+#define ROP4_COPY		0xCCCC
+#define ROP4_INVERT		0x3333
+
+/* Hardware limits */
+#define MAX_WIDTH		8000
+#define MAX_HEIGHT		8000
+
+#define G2D_TIMEOUT		500
+
+#define DEFAULT_WIDTH		100
+#define DEFAULT_HEIGHT		100
+
diff --git a/drivers/media/video/s5p-g2d/g2d.c b/drivers/media/video/s5p-g2d/g2d.c
new file mode 100644
index 0000000..1f156c8
--- /dev/null
+++ b/drivers/media/video/s5p-g2d/g2d.c
@@ -0,0 +1,824 @@
+/*
+ * Samsung S5P G2D - 2D Graphics Accelerator Driver
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * Kamil Debski, <k.debski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/version.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+
+#include <linux/platform_device.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "g2d.h"
+#include "g2d-regs.h"
+
+#define fh2ctx(__fh) container_of(__fh, struct g2d_ctx, fh)
+
+static struct g2d_fmt formats[] = {
+	{
+		.name	= "XRGB_8888",
+		.fourcc	= V4L2_PIX_FMT_RGB32,
+		.depth	= 32,
+		.hw	= COLOR_MODE(ORDER_XRGB, MODE_XRGB_8888),
+	},
+	{
+		.name	= "RGB_565",
+		.fourcc	= V4L2_PIX_FMT_RGB565X,
+		.depth	= 16,
+		.hw	= COLOR_MODE(ORDER_XRGB, MODE_RGB_565),
+	},
+	{
+		.name	= "XRGB_1555",
+		.fourcc	= V4L2_PIX_FMT_RGB555X,
+		.depth	= 16,
+		.hw	= COLOR_MODE(ORDER_XRGB, MODE_XRGB_1555),
+	},
+	{
+		.name	= "XRGB_4444",
+		.fourcc	= V4L2_PIX_FMT_RGB444,
+		.depth	= 16,
+		.hw	= COLOR_MODE(ORDER_XRGB, MODE_XRGB_4444),
+	},
+	{
+		.name	= "PACKED_RGB_888",
+		.fourcc	= V4L2_PIX_FMT_RGB24,
+		.depth	= 24,
+		.hw	= COLOR_MODE(ORDER_XRGB, MODE_PACKED_RGB_888),
+	},
+};
+#define NUM_FORMATS ARRAY_SIZE(formats)
+
+struct g2d_frame def_frame = {
+	.width		= DEFAULT_WIDTH,
+	.height		= DEFAULT_HEIGHT,
+	.c_width	= DEFAULT_WIDTH,
+	.c_height	= DEFAULT_HEIGHT,
+	.o_width	= 0,
+	.o_height	= 0,
+	.fmt		= &formats[0],
+	.right		= DEFAULT_WIDTH,
+	.bottom		= DEFAULT_HEIGHT,
+};
+
+struct g2d_fmt *find_fmt(struct v4l2_format *f)
+{
+	unsigned int i;
+	for (i = 0; i < NUM_FORMATS; i++) {
+		if (formats[i].fourcc == f->fmt.pix.pixelformat)
+			return &formats[i];
+	}
+	return NULL;
+}
+
+
+static struct g2d_frame *get_frame(struct g2d_ctx *ctx,
+							enum v4l2_buf_type type)
+{
+	switch (type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+		return &ctx->in;
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		return &ctx->out;
+	default:
+		return ERR_PTR(-EINVAL);
+	}
+}
+
+static int g2d_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+			   unsigned int *nbuffers, unsigned int *nplanes,
+			   unsigned int sizes[], void *alloc_ctxs[])
+{
+	struct g2d_ctx *ctx = vb2_get_drv_priv(vq);
+	struct g2d_frame *f = get_frame(ctx, vq->type);
+
+	if (IS_ERR(f))
+		return PTR_ERR(f);
+
+	sizes[0] = f->size;
+	*nplanes = 1;
+	alloc_ctxs[0] = ctx->dev->alloc_ctx;
+
+	if (*nbuffers == 0)
+		*nbuffers = 1;
+
+	return 0;
+}
+
+static int g2d_buf_prepare(struct vb2_buffer *vb)
+{
+	struct g2d_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+	struct g2d_frame *f = get_frame(ctx, vb->vb2_queue->type);
+
+	if (IS_ERR(f))
+		return PTR_ERR(f);
+	vb2_set_plane_payload(vb, 0, f->size);
+	return 0;
+}
+
+static void g2d_buf_queue(struct vb2_buffer *vb)
+{
+	struct g2d_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+	v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
+}
+
+
+static struct vb2_ops g2d_qops = {
+	.queue_setup	= g2d_queue_setup,
+	.buf_prepare	= g2d_buf_prepare,
+	.buf_queue	= g2d_buf_queue,
+};
+
+static int queue_init(void *priv, struct vb2_queue *src_vq,
+						struct vb2_queue *dst_vq)
+{
+	struct g2d_ctx *ctx = priv;
+	int ret;
+
+	memset(src_vq, 0, sizeof(*src_vq));
+	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+	src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+	src_vq->drv_priv = ctx;
+	src_vq->ops = &g2d_qops;
+	src_vq->mem_ops = &vb2_dma_contig_memops;
+	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+
+	ret = vb2_queue_init(src_vq);
+	if (ret)
+		return ret;
+
+	memset(dst_vq, 0, sizeof(*dst_vq));
+	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+	dst_vq->drv_priv = ctx;
+	dst_vq->ops = &g2d_qops;
+	dst_vq->mem_ops = &vb2_dma_contig_memops;
+	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+
+	return vb2_queue_init(dst_vq);
+}
+
+static int g2d_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct g2d_ctx *ctx = container_of(ctrl->handler, struct g2d_ctx,
+								ctrl_handler);
+	switch (ctrl->id) {
+	case V4L2_CID_COLORFX:
+		if (ctrl->val == V4L2_COLORFX_NEGATIVE)
+			ctx->rop = ROP4_INVERT;
+		else
+			ctx->rop = ROP4_COPY;
+	default:
+		v4l2_err(&ctx->dev->v4l2_dev, "unknown control\n");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops g2d_ctrl_ops = {
+	.s_ctrl		= g2d_s_ctrl,
+};
+
+int g2d_setup_ctrls(struct g2d_ctx *ctx)
+{
+	struct g2d_dev *dev = ctx->dev;
+
+	v4l2_ctrl_handler_init(&ctx->ctrl_handler, 1);
+	if (ctx->ctrl_handler.error) {
+		v4l2_err(&dev->v4l2_dev, "v4l2_ctrl_handler_init failed\n");
+		return ctx->ctrl_handler.error;
+	}
+
+	v4l2_ctrl_new_std_menu(
+		&ctx->ctrl_handler,
+		&g2d_ctrl_ops,
+		V4L2_CID_COLORFX,
+		V4L2_COLORFX_NEGATIVE,
+		~((1 << V4L2_COLORFX_NONE) | (1 << V4L2_COLORFX_NEGATIVE)),
+		V4L2_COLORFX_NONE);
+
+	if (ctx->ctrl_handler.error) {
+		v4l2_err(&dev->v4l2_dev, "v4l2_ctrl_handler_init failed\n");
+		return ctx->ctrl_handler.error;
+	}
+
+	return 0;
+}
+
+static int g2d_open(struct file *file)
+{
+	struct g2d_dev *dev = video_drvdata(file);
+	struct g2d_ctx *ctx = NULL;
+	int ret = 0;
+
+	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+	ctx->dev = dev;
+	/* Set default formats */
+	ctx->in		= def_frame;
+	ctx->out	= def_frame;
+
+	ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
+	if (IS_ERR(ctx->m2m_ctx)) {
+		ret = PTR_ERR(ctx->m2m_ctx);
+		kfree(ctx);
+		return ret;
+	}
+	v4l2_fh_init(&ctx->fh, video_devdata(file));
+	file->private_data = &ctx->fh;
+	v4l2_fh_add(&ctx->fh);
+
+	g2d_setup_ctrls(ctx);
+
+	/* Write the default values to the ctx struct */
+	v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
+
+	ctx->fh.ctrl_handler = &ctx->ctrl_handler;
+
+	v4l2_info(&dev->v4l2_dev, "instance opened\n");
+	return 0;
+}
+
+static int g2d_release(struct file *file)
+{
+	struct g2d_dev *dev = video_drvdata(file);
+	struct g2d_ctx *ctx = fh2ctx(file->private_data);
+
+	v4l2_ctrl_handler_free(&ctx->ctrl_handler);
+	v4l2_fh_del(&ctx->fh);
+	v4l2_fh_exit(&ctx->fh);
+	kfree(ctx);
+	v4l2_info(&dev->v4l2_dev, "instance closed\n");
+	return 0;
+}
+
+
+static int vidioc_querycap(struct file *file, void *priv,
+				struct v4l2_capability *cap)
+{
+	strncpy(cap->driver, G2D_NAME, sizeof(cap->driver) - 1);
+	strncpy(cap->card, G2D_NAME, sizeof(cap->card) - 1);
+	cap->bus_info[0] = 0;
+	cap->version = KERNEL_VERSION(1, 0, 0);
+	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT
+							| V4L2_CAP_STREAMING;
+	return 0;
+}
+
+static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f)
+{
+	struct g2d_fmt *fmt;
+	if (f->index >= NUM_FORMATS)
+		return -EINVAL;
+	fmt = &formats[f->index];
+	f->pixelformat = fmt->fourcc;
+	strncpy(f->description, fmt->name, sizeof(f->description) - 1);
+	return 0;
+}
+
+static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f)
+{
+	struct g2d_ctx *ctx = prv;
+	struct vb2_queue *vq;
+	struct g2d_frame *frm;
+
+	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
+	if (!vq)
+		return -EINVAL;
+	frm = get_frame(ctx, f->type);
+	if (IS_ERR(frm))
+		return PTR_ERR(frm);
+
+	f->fmt.pix.width		= frm->width;
+	f->fmt.pix.height		= frm->height;
+	f->fmt.pix.field		= V4L2_FIELD_NONE;
+	f->fmt.pix.pixelformat		= frm->fmt->fourcc;
+	f->fmt.pix.bytesperline		= (frm->width * frm->fmt->depth) >> 3;
+	f->fmt.pix.sizeimage		= frm->size;
+	return 0;
+}
+
+static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f)
+{
+	struct g2d_fmt *fmt;
+	enum v4l2_field *field;
+
+	fmt = find_fmt(f);
+	if (!fmt)
+		return -EINVAL;
+
+	field = &f->fmt.pix.field;
+	if (*field == V4L2_FIELD_ANY)
+		*field = V4L2_FIELD_NONE;
+	else if (*field != V4L2_FIELD_NONE)
+		return -EINVAL;
+
+	if (f->fmt.pix.width > MAX_WIDTH)
+		f->fmt.pix.width = MAX_WIDTH;
+	if (f->fmt.pix.height > MAX_HEIGHT)
+		f->fmt.pix.height = MAX_HEIGHT;
+
+	if (f->fmt.pix.width < 1)
+		f->fmt.pix.width = 1;
+	if (f->fmt.pix.height < 1)
+		f->fmt.pix.height = 1;
+
+	f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
+	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
+	return 0;
+}
+
+static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
+{
+	struct g2d_ctx *ctx = prv;
+	struct g2d_dev *dev = ctx->dev;
+	struct vb2_queue *vq;
+	struct g2d_frame *frm;
+	struct g2d_fmt *fmt;
+	int ret = 0;
+
+	/* Adjust all values accordingly to the hardware capabilities
+	 * and chosen format. */
+	ret = vidioc_try_fmt(file, prv, f);
+	if (ret)
+		return ret;
+	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
+	if (vb2_is_busy(vq)) {
+		v4l2_err(&dev->v4l2_dev, "queue (%d) bust\n", f->type);
+		return -EBUSY;
+	}
+	frm = get_frame(ctx, f->type);
+	if (IS_ERR(frm))
+		return PTR_ERR(frm);
+	fmt = find_fmt(f);
+	if (!fmt)
+		return -EINVAL;
+	frm->width	= f->fmt.pix.width;
+	frm->height	= f->fmt.pix.height;
+	frm->size	= f->fmt.pix.sizeimage;
+	/* Reset crop settings */
+	frm->o_width	= 0;
+	frm->o_height	= 0;
+	frm->c_width	= frm->width;
+	frm->c_height	= frm->height;
+	frm->right	= frm->width;
+	frm->bottom	= frm->height;
+	frm->fmt	= fmt;
+	frm->stride	= f->fmt.pix.bytesperline;
+	return 0;
+}
+
+static unsigned int g2d_poll(struct file *file, struct poll_table_struct *wait)
+{
+	struct g2d_ctx *ctx = fh2ctx(file->private_data);
+	return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
+}
+
+static int g2d_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct g2d_ctx *ctx = fh2ctx(file->private_data);
+	return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
+}
+
+static int vidioc_reqbufs(struct file *file, void *priv,
+			struct v4l2_requestbuffers *reqbufs)
+{
+	struct g2d_ctx *ctx = priv;
+	return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
+}
+
+static int vidioc_querybuf(struct file *file, void *priv,
+			struct v4l2_buffer *buf)
+{
+	struct g2d_ctx *ctx = priv;
+	return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
+}
+
+static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+	struct g2d_ctx *ctx = priv;
+	return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+	struct g2d_ctx *ctx = priv;
+	return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
+}
+
+
+static int vidioc_streamon(struct file *file, void *priv,
+					enum v4l2_buf_type type)
+{
+	struct g2d_ctx *ctx = priv;
+	return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
+}
+
+static int vidioc_streamoff(struct file *file, void *priv,
+					enum v4l2_buf_type type)
+{
+	struct g2d_ctx *ctx = priv;
+	return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
+}
+
+static int vidioc_cropcap(struct file *file, void *priv,
+					struct v4l2_cropcap *cr)
+{
+	struct g2d_ctx *ctx = priv;
+	struct g2d_frame *f;
+
+	f = get_frame(ctx, cr->type);
+	if (IS_ERR(f))
+		return PTR_ERR(f);
+
+	cr->bounds.left		= 0;
+	cr->bounds.top		= 0;
+	cr->bounds.width	= f->width;
+	cr->bounds.height	= f->height;
+	cr->defrect		= cr->bounds;
+	return 0;
+}
+
+static int vidioc_g_crop(struct file *file, void *prv, struct v4l2_crop *cr)
+{
+	struct g2d_ctx *ctx = prv;
+	struct g2d_frame *f;
+
+	f = get_frame(ctx, cr->type);
+	if (IS_ERR(f))
+		return PTR_ERR(f);
+
+	cr->c.left	= f->o_height;
+	cr->c.top	= f->o_width;
+	cr->c.width	= f->c_width;
+	cr->c.height	= f->c_height;
+	return 0;
+}
+
+static int vidioc_try_crop(struct file *file, void *prv, struct v4l2_crop *cr)
+{
+	struct g2d_ctx *ctx = prv;
+	struct g2d_dev *dev = ctx->dev;
+	struct g2d_frame *f;
+
+	f = get_frame(ctx, cr->type);
+	if (IS_ERR(f))
+		return PTR_ERR(f);
+
+	if (cr->c.top < 0 || cr->c.left < 0) {
+		v4l2_err(&dev->v4l2_dev,
+			"doesn't support negative values for top & left\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vidioc_s_crop(struct file *file, void *prv, struct v4l2_crop *cr)
+{
+	struct g2d_ctx *ctx = prv;
+	struct g2d_frame *f;
+	int ret;
+
+	ret = vidioc_try_crop(file, prv, cr);
+	if (ret)
+		return ret;
+	f = get_frame(ctx, cr->type);
+	if (IS_ERR(f))
+		return PTR_ERR(f);
+
+	f->c_width	= cr->c.width;
+	f->c_height	= cr->c.height;
+	f->o_width	= cr->c.left;
+	f->o_height	= cr->c.top;
+	f->bottom	= f->o_height + f->c_height;
+	f->right	= f->o_width + f->c_width;
+	return 0;
+}
+
+static void g2d_lock(void *prv)
+{
+	struct g2d_ctx *ctx = prv;
+	struct g2d_dev *dev = ctx->dev;
+	mutex_lock(&dev->mutex);
+}
+
+static void g2d_unlock(void *prv)
+{
+	struct g2d_ctx *ctx = prv;
+	struct g2d_dev *dev = ctx->dev;
+	mutex_unlock(&dev->mutex);
+}
+
+static void job_abort(void *prv)
+{
+	struct g2d_ctx *ctx = prv;
+	struct g2d_dev *dev = ctx->dev;
+	int ret;
+
+	if (dev->curr == 0) /* No job currently running */
+		return;
+
+	ret = wait_event_timeout(dev->irq_queue,
+		dev->curr == 0,
+		msecs_to_jiffies(G2D_TIMEOUT));
+}
+
+static void device_run(void *prv)
+{
+	struct g2d_ctx *ctx = prv;
+	struct g2d_dev *dev = ctx->dev;
+	struct vb2_buffer *src, *dst;
+	u32 cmd = 0;
+
+	dev->curr = ctx;
+
+	src = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
+	dst = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+
+	clk_enable(dev->gate);
+	g2d_reset(dev);
+
+	g2d_set_src_size(dev, &ctx->in);
+	g2d_set_src_addr(dev, vb2_dma_contig_plane_dma_addr(src, 0));
+
+	g2d_set_dst_size(dev, &ctx->out);
+	g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0));
+
+	g2d_set_rop4(dev, ctx->rop);
+	if (ctx->in.c_width != ctx->out.c_width ||
+		ctx->in.c_height != ctx->out.c_height)
+		cmd |= g2d_cmd_stretch(1);
+	g2d_set_cmd(dev, cmd);
+	g2d_start(dev);
+}
+
+static irqreturn_t g2d_isr(int irq, void *prv)
+{
+	struct g2d_dev *dev = prv;
+	struct g2d_ctx *ctx = dev->curr;
+	struct vb2_buffer *src, *dst;
+
+	g2d_clear_int(dev);
+	clk_disable(dev->gate);
+
+	BUG_ON(ctx == 0);
+
+	src = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+	dst = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
+
+	BUG_ON(src == 0);
+	BUG_ON(dst == 0);
+
+	v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE);
+	v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE);
+	v4l2_m2m_job_finish(dev->m2m_dev, ctx->m2m_ctx);
+
+	dev->curr = 0;
+	wake_up(&dev->irq_queue);
+	return IRQ_HANDLED;
+}
+
+static const struct v4l2_file_operations g2d_fops = {
+	.owner		= THIS_MODULE,
+	.open		= g2d_open,
+	.release	= g2d_release,
+	.poll		= g2d_poll,
+	.unlocked_ioctl	= video_ioctl2,
+	.mmap		= g2d_mmap,
+};
+
+static const struct v4l2_ioctl_ops g2d_ioctl_ops = {
+	.vidioc_querycap	= vidioc_querycap,
+
+	.vidioc_enum_fmt_vid_cap	= vidioc_enum_fmt,
+	.vidioc_g_fmt_vid_cap		= vidioc_g_fmt,
+	.vidioc_try_fmt_vid_cap		= vidioc_try_fmt,
+	.vidioc_s_fmt_vid_cap		= vidioc_s_fmt,
+
+	.vidioc_enum_fmt_vid_out	= vidioc_enum_fmt,
+	.vidioc_g_fmt_vid_out		= vidioc_g_fmt,
+	.vidioc_try_fmt_vid_out		= vidioc_try_fmt,
+	.vidioc_s_fmt_vid_out		= vidioc_s_fmt,
+
+	.vidioc_reqbufs			= vidioc_reqbufs,
+	.vidioc_querybuf		= vidioc_querybuf,
+
+	.vidioc_qbuf			= vidioc_qbuf,
+	.vidioc_dqbuf			= vidioc_dqbuf,
+
+	.vidioc_streamon		= vidioc_streamon,
+	.vidioc_streamoff		= vidioc_streamoff,
+
+	.vidioc_g_crop			= vidioc_g_crop,
+	.vidioc_s_crop			= vidioc_s_crop,
+	.vidioc_cropcap			= vidioc_cropcap,
+};
+
+static struct video_device g2d_videodev = {
+	.name		= G2D_NAME,
+	.fops		= &g2d_fops,
+	.ioctl_ops	= &g2d_ioctl_ops,
+	.minor		= -1,
+	.release	= video_device_release,
+};
+
+static struct v4l2_m2m_ops g2d_m2m_ops = {
+	.device_run	= device_run,
+	.job_abort	= job_abort,
+	.lock		= g2d_lock,
+	.unlock		= g2d_unlock,
+};
+
+static int g2d_probe(struct platform_device *pdev)
+{
+	struct g2d_dev *dev;
+	struct video_device *vfd;
+	struct resource *res;
+	int ret = 0;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+	spin_lock_init(&dev->irqlock);
+	mutex_init(&dev->mutex);
+	atomic_set(&dev->num_inst, 0);
+	init_waitqueue_head(&dev->irq_queue);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "failed to find registers\n");
+		ret = -ENOENT;
+		goto free_dev;
+	}
+
+	dev->res_regs = request_mem_region(res->start, resource_size(res),
+						dev_name(&pdev->dev));
+
+	if (!dev->res_regs) {
+		dev_err(&pdev->dev, "failed to obtain register region\n");
+		ret = -ENOENT;
+		goto free_dev;
+	}
+
+	dev->regs = ioremap(res->start, resource_size(res));
+	if (!dev->regs) {
+		dev_err(&pdev->dev, "failed to map registers\n");
+		ret = -ENOENT;
+		goto rel_res_regs;
+	}
+
+	dev->clk = clk_get(&pdev->dev, "sclk_fimg2d");
+	if (IS_ERR_OR_NULL(dev->clk)) {
+		dev_err(&pdev->dev, "failed to get g2d clock\n");
+		ret = -ENXIO;
+		goto unmap_regs;
+	}
+
+	dev->gate = clk_get(&pdev->dev, "fimg2d");
+	if (IS_ERR_OR_NULL(dev->gate)) {
+		dev_err(&pdev->dev, "failed to get g2d clock gate\n");
+		ret = -ENXIO;
+		goto put_clk;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "failed to find IRQ\n");
+		ret = -ENXIO;
+		goto put_clk_gate;
+	}
+
+	dev->irq = res->start;
+
+	ret = request_irq(dev->irq, g2d_isr, 0, pdev->name, dev);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to install IRQ\n");
+		goto put_clk_gate;
+	}
+
+	dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
+	if (IS_ERR(dev->alloc_ctx)) {
+		ret = PTR_ERR(dev->alloc_ctx);
+		goto rel_irq;
+	}
+
+	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
+	if (ret)
+		goto alloc_ctx_cleanup;
+	vfd = video_device_alloc();
+	if (!vfd) {
+		v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
+		ret = -ENOMEM;
+		goto unreg_v4l2_dev;
+	}
+	*vfd = g2d_videodev;
+	vfd->lock = &dev->mutex;
+	ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
+	if (ret) {
+		v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
+		goto rel_vdev;
+	}
+	video_set_drvdata(vfd, dev);
+	snprintf(vfd->name, sizeof(vfd->name), "%s", g2d_videodev.name);
+	dev->vfd = vfd;
+	v4l2_info(&dev->v4l2_dev, "device registered as /dev/video%d\n",
+								vfd->num);
+	platform_set_drvdata(pdev, dev);
+	dev->m2m_dev = v4l2_m2m_init(&g2d_m2m_ops);
+	if (IS_ERR(dev->m2m_dev)) {
+		v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
+		ret = PTR_ERR(dev->m2m_dev);
+		goto unreg_video_dev;
+	}
+
+	def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3;
+
+	return 0;
+
+unreg_video_dev:
+	video_unregister_device(dev->vfd);
+rel_vdev:
+	video_device_release(vfd);
+unreg_v4l2_dev:
+	v4l2_device_unregister(&dev->v4l2_dev);
+alloc_ctx_cleanup:
+	vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
+rel_irq:
+	free_irq(dev->irq, dev);
+put_clk_gate:
+	clk_put(dev->gate);
+put_clk:
+	clk_put(dev->clk);
+unmap_regs:
+	iounmap(dev->regs);
+rel_res_regs:
+	release_resource(dev->res_regs);
+free_dev:
+	kfree(dev);
+	return ret;
+}
+
+static int g2d_remove(struct platform_device *pdev)
+{
+	struct g2d_dev *dev = (struct g2d_dev *)platform_get_drvdata(pdev);
+
+	v4l2_info(&dev->v4l2_dev, "Removing " G2D_NAME);
+	v4l2_m2m_release(dev->m2m_dev);
+	video_unregister_device(dev->vfd);
+	v4l2_device_unregister(&dev->v4l2_dev);
+	vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
+	free_irq(dev->irq, dev);
+	clk_put(dev->gate);
+	clk_put(dev->clk);
+	iounmap(dev->regs);
+	release_resource(dev->res_regs);
+	kfree(dev);
+	return 0;
+}
+
+static struct platform_driver g2d_pdrv = {
+	.probe		= g2d_probe,
+	.remove		= g2d_remove,
+	.driver		= {
+		.name = G2D_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static void __exit g2d_exit(void)
+{
+	platform_driver_unregister(&g2d_pdrv);
+};
+
+static int  __init g2d_init(void)
+{
+	int ret = 0;
+
+	ret = platform_driver_register(&g2d_pdrv);
+	return ret;
+};
+
+module_init(g2d_init);
+module_exit(g2d_exit);
+
+MODULE_AUTHOR("Kamil Debski <k.debski@samsung.com>");
+MODULE_DESCRIPTION("S5P G2D 2d graphics accelerator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/s5p-g2d/g2d.h b/drivers/media/video/s5p-g2d/g2d.h
new file mode 100644
index 0000000..5eae901
--- /dev/null
+++ b/drivers/media/video/s5p-g2d/g2d.h
@@ -0,0 +1,83 @@
+/*
+ * Samsung S5P G2D - 2D Graphics Accelerator Driver
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * Kamil Debski, <k.debski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version
+ */
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+
+#define G2D_NAME "s5p-g2d"
+
+struct g2d_dev {
+	struct v4l2_device	v4l2_dev;
+	struct v4l2_m2m_dev	*m2m_dev;
+	struct video_device	*vfd;
+	struct mutex		mutex;
+	spinlock_t		irqlock;
+	atomic_t		num_inst;
+	struct vb2_alloc_ctx	*alloc_ctx;
+	struct resource		*res_regs;
+	void __iomem		*regs;
+	struct clk		*clk;
+	struct clk		*gate;
+	struct g2d_ctx		*curr;
+	int irq;
+	wait_queue_head_t	irq_queue;
+};
+
+struct g2d_frame {
+	/* Original dimensions */
+	u32	width;
+	u32	height;
+	/* Crop size */
+	u32	c_width;
+	u32	c_height;
+	/* Offset */
+	u32	o_width;
+	u32	o_height;
+	/* Image format */
+	struct g2d_fmt *fmt;
+	/* Variables that can calculated once and reused */
+	u32	stride;
+	u32	bottom;
+	u32	right;
+	u32	size;
+};
+
+struct g2d_ctx {
+	struct v4l2_fh fh;
+	struct g2d_dev		*dev;
+	struct v4l2_m2m_ctx     *m2m_ctx;
+	struct g2d_frame	in;
+	struct g2d_frame	out;
+	struct v4l2_ctrl_handler ctrl_handler;
+	u32 rop;
+};
+
+struct g2d_fmt {
+	char	*name;
+	u32	fourcc;
+	int	depth;
+	u32	hw;
+};
+
+
+void g2d_reset(struct g2d_dev *d);
+void g2d_set_src_size(struct g2d_dev *d, struct g2d_frame *f);
+void g2d_set_src_addr(struct g2d_dev *d, dma_addr_t a);
+void g2d_set_dst_size(struct g2d_dev *d, struct g2d_frame *f);
+void g2d_set_dst_addr(struct g2d_dev *d, dma_addr_t a);
+void g2d_start(struct g2d_dev *d);
+void g2d_clear_int(struct g2d_dev *d);
+void g2d_set_rop4(struct g2d_dev *d, u32 r);
+u32 g2d_cmd_stretch(u32 e);
+void g2d_set_cmd(struct g2d_dev *d, u32 c);
+
+
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 0f9fb99..065d0f6 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -5691,6 +5691,27 @@
 			.amux = LINE1,
 		},
 	},
+	[SAA7134_BOARD_SENSORAY811_911] = {
+		.name		= "Sensoray 811/911",
+		.audio_clock	= 0x00200000,
+		.tuner_type	= TUNER_ABSENT,
+		.radio_type	= UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.inputs		= {{
+			.name   = name_comp1,
+			.vmux   = 0,
+			.amux   = LINE1,
+		}, {
+			.name   = name_comp3,
+			.vmux   = 2,
+			.amux   = LINE1,
+		}, {
+			.name   = name_svideo,
+			.vmux   = 8,
+			.amux   = LINE1,
+		} },
+	},
 
 };
 
@@ -6914,6 +6935,18 @@
 		.subdevice    = 0xd136,
 		.driver_data  = SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2,
 	}, {
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x6000,
+		.subdevice    = 0x0811,
+		.driver_data  = SAA7134_BOARD_SENSORAY811_911,
+	}, {
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x6000,
+		.subdevice    = 0x0911,
+		.driver_data  = SAA7134_BOARD_SENSORAY811_911,
+	}, {
 		/* --- boards without eeprom + subsystem ID --- */
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 9b55068..4ad9de4 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -330,6 +330,7 @@
 #define SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2 185
 #define SAA7134_BOARD_BEHOLD_501            186
 #define SAA7134_BOARD_BEHOLD_503FM          187
+#define SAA7134_BOARD_SENSORAY811_911       188
 
 #define SAA7134_MAXBOARDS 32
 #define SAA7134_INPUT_MAX 8
diff --git a/drivers/media/video/saa7164/saa7164-bus.c b/drivers/media/video/saa7164/saa7164-bus.c
index 466e1b0..a7f58a9 100644
--- a/drivers/media/video/saa7164/saa7164-bus.c
+++ b/drivers/media/video/saa7164/saa7164-bus.c
@@ -149,7 +149,7 @@
 	saa7164_bus_verify(dev);
 
 	msg->size = cpu_to_le16(msg->size);
-	msg->command = cpu_to_le16(msg->command);
+	msg->command = cpu_to_le32(msg->command);
 	msg->controlselector = cpu_to_le16(msg->controlselector);
 
 	if (msg->size > dev->bus.m_wMaxReqSize) {
@@ -464,7 +464,7 @@
 
 peekout:
 	msg->size = le16_to_cpu(msg->size);
-	msg->command = le16_to_cpu(msg->command);
+	msg->command = le32_to_cpu(msg->command);
 	msg->controlselector = le16_to_cpu(msg->controlselector);
 	ret = SAA_OK;
 out:
diff --git a/drivers/media/video/tm6000/Kconfig b/drivers/media/video/tm6000/Kconfig
index 114eec8..a43b77a 100644
--- a/drivers/media/video/tm6000/Kconfig
+++ b/drivers/media/video/tm6000/Kconfig
@@ -1,6 +1,6 @@
 config VIDEO_TM6000
 	tristate "TV Master TM5600/6000/6010 driver"
-	depends on VIDEO_DEV && I2C && INPUT && RC_CORE && USB && EXPERIMENTAL
+	depends on VIDEO_DEV && I2C && INPUT && RC_CORE && USB
 	select VIDEO_TUNER
 	select MEDIA_TUNER_XC2028
 	select MEDIA_TUNER_XC5000
@@ -16,7 +16,7 @@
 
 config VIDEO_TM6000_ALSA
 	tristate "TV Master TM5600/6000/6010 audio support"
-	depends on VIDEO_TM6000 && SND && EXPERIMENTAL
+	depends on VIDEO_TM6000 && SND
 	select SND_PCM
 	---help---
 	  This is a video4linux driver for direct (DMA) audio for
@@ -27,7 +27,7 @@
 
 config VIDEO_TM6000_DVB
 	tristate "DVB Support for tm6000 based TV cards"
-	depends on VIDEO_TM6000 && DVB_CORE && USB && EXPERIMENTAL
+	depends on VIDEO_TM6000 && DVB_CORE && USB
 	select DVB_ZL10353
 	---help---
 	  This adds support for DVB cards based on the tm5600/tm6000 chip.
diff --git a/drivers/media/video/tm6000/tm6000-alsa.c b/drivers/media/video/tm6000/tm6000-alsa.c
index 7d675c72..ddffd67 100644
--- a/drivers/media/video/tm6000/tm6000-alsa.c
+++ b/drivers/media/video/tm6000/tm6000-alsa.c
@@ -146,20 +146,21 @@
 #define DEFAULT_FIFO_SIZE	4096
 
 static struct snd_pcm_hardware snd_tm6000_digital_hw = {
-	.info = SNDRV_PCM_INFO_MMAP |
+	.info = SNDRV_PCM_INFO_BATCH |
+		SNDRV_PCM_INFO_MMAP |
 		SNDRV_PCM_INFO_INTERLEAVED |
 		SNDRV_PCM_INFO_BLOCK_TRANSFER |
 		SNDRV_PCM_INFO_MMAP_VALID,
 	.formats = SNDRV_PCM_FMTBIT_S16_LE,
 
-	.rates = SNDRV_PCM_RATE_CONTINUOUS,
+	.rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_KNOT,
 	.rate_min = 48000,
 	.rate_max = 48000,
 	.channels_min = 2,
 	.channels_max = 2,
 	.period_bytes_min = 64,
 	.period_bytes_max = 12544,
-	.periods_min = 1,
+	.periods_min = 2,
 	.periods_max = 98,
 	.buffer_bytes_max = 62720 * 8,
 };
@@ -181,6 +182,7 @@
 	chip->substream = substream;
 
 	runtime->hw = snd_tm6000_digital_hw;
+	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
 
 	return 0;
 _error:
@@ -347,9 +349,13 @@
 	int err = 0;
 
 	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
+	case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
 	case SNDRV_PCM_TRIGGER_START:
 		atomic_set(&core->stream_started, 1);
 		break;
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */
+	case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */
 	case SNDRV_PCM_TRIGGER_STOP:
 		atomic_set(&core->stream_started, 0);
 		break;
@@ -371,6 +377,14 @@
 	return chip->buf_pos;
 }
 
+static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
+					     unsigned long offset)
+{
+	void *pageptr = subs->runtime->dma_area + offset;
+
+	return vmalloc_to_page(pageptr);
+}
+
 /*
  * operators
  */
@@ -383,6 +397,7 @@
 	.prepare = snd_tm6000_prepare,
 	.trigger = snd_tm6000_card_trigger,
 	.pointer = snd_tm6000_pointer,
+	.page = snd_pcm_get_vmalloc_page,
 };
 
 /*
diff --git a/drivers/media/video/tm6000/tm6000-cards.c b/drivers/media/video/tm6000/tm6000-cards.c
index ec2578a..6b74259 100644
--- a/drivers/media/video/tm6000/tm6000-cards.c
+++ b/drivers/media/video/tm6000/tm6000-cards.c
@@ -351,6 +351,7 @@
 		.tuner_addr   = 0xc2 >> 1,
 		.demod_addr   = 0x1e >> 1,
 		.type         = TM6010,
+		.ir_codes = RC_MAP_HAUPPAUGE,
 		.caps = {
 			.has_tuner    = 1,
 			.has_dvb      = 1,
@@ -639,6 +640,7 @@
 	{ USB_DEVICE(0x6000, 0xdec3), .driver_info = TM6010_BOARD_BEHOLD_VOYAGER_LITE },
 	{ }
 };
+MODULE_DEVICE_TABLE(usb, tm6000_id_table);
 
 /* Control power led for show some activity */
 void tm6000_flash_led(struct tm6000_core *dev, u8 state)
@@ -1050,6 +1052,33 @@
 	       tm6000_boards[model].name, model);
 }
 
+#if defined(CONFIG_MODULES) && defined(MODULE)
+static void request_module_async(struct work_struct *work)
+{
+	struct tm6000_core *dev = container_of(work, struct tm6000_core,
+					       request_module_wk);
+
+	request_module("tm6000-alsa");
+
+	if (dev->caps.has_dvb)
+		request_module("tm6000-dvb");
+}
+
+static void request_modules(struct tm6000_core *dev)
+{
+	INIT_WORK(&dev->request_module_wk, request_module_async);
+	schedule_work(&dev->request_module_wk);
+}
+
+static void flush_request_modules(struct tm6000_core *dev)
+{
+	flush_work_sync(&dev->request_module_wk);
+}
+#else
+#define request_modules(dev)
+#define flush_request_modules(dev)
+#endif /* CONFIG_MODULES */
+
 static int tm6000_init_dev(struct tm6000_core *dev)
 {
 	struct v4l2_frequency f;
@@ -1112,6 +1141,8 @@
 
 	tm6000_ir_init(dev);
 
+	request_modules(dev);
+
 	mutex_unlock(&dev->lock);
 	return 0;
 
@@ -1324,6 +1355,8 @@
 
 	printk(KERN_INFO "tm6000: disconnecting %s\n", dev->name);
 
+	flush_request_modules(dev);
+
 	tm6000_ir_fini(dev);
 
 	if (dev->gpio.power_led) {
diff --git a/drivers/media/video/tm6000/tm6000-core.c b/drivers/media/video/tm6000/tm6000-core.c
index 9783616..979c85b 100644
--- a/drivers/media/video/tm6000/tm6000-core.c
+++ b/drivers/media/video/tm6000/tm6000-core.c
@@ -88,7 +88,9 @@
 	}
 
 	kfree(data);
-	msleep(5);
+
+	if ((dev->quirks & TM6000_QUIRK_NO_USB_DELAY) == 0)
+		msleep(5);
 
 	mutex_unlock(&dev->usb_lock);
 	return ret;
@@ -125,14 +127,14 @@
 	u8 new_index;
 
 	rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
-					value, index, buf, 1);
+					value, 0, buf, 1);
 
 	if (rc < 0)
 		return rc;
 
 	new_index = (buf[0] & ~mask) | (index & mask);
 
-	if (new_index == index)
+	if (new_index == buf[0])
 		return 0;
 
 	return tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR,
@@ -536,16 +538,16 @@
 
 	{ TM6010_REQ05_R18_IMASK7, 0x00 },
 
-	{ TM6010_REQ07_RD8_IR_LEADER1, 0xaa },
-	{ TM6010_REQ07_RD8_IR_LEADER0, 0x30 },
-	{ TM6010_REQ07_RD8_IR_PULSE_CNT1, 0x20 },
-	{ TM6010_REQ07_RD8_IR_PULSE_CNT0, 0xd0 },
+	{ TM6010_REQ07_RDC_IR_LEADER1, 0xaa },
+	{ TM6010_REQ07_RDD_IR_LEADER0, 0x30 },
+	{ TM6010_REQ07_RDE_IR_PULSE_CNT1, 0x20 },
+	{ TM6010_REQ07_RDF_IR_PULSE_CNT0, 0xd0 },
 	{ REQ_04_EN_DISABLE_MCU_INT, 0x02, 0x00 },
-	{ TM6010_REQ07_RD8_IR, 0x2f },
+	{ TM6010_REQ07_RD8_IR, 0x0f },
 
 	/* set remote wakeup key:any key wakeup */
 	{ TM6010_REQ07_RE5_REMOTE_WAKEUP,  0xfe },
-	{ TM6010_REQ07_RD8_IR_WAKEUP_SEL,  0xff },
+	{ TM6010_REQ07_RDA_IR_WAKEUP_SEL,  0xff },
 };
 
 int tm6000_init(struct tm6000_core *dev)
@@ -599,55 +601,6 @@
 	return rc;
 }
 
-int tm6000_reset(struct tm6000_core *dev)
-{
-	int pipe;
-	int err;
-
-	msleep(500);
-
-	err = usb_set_interface(dev->udev, dev->isoc_in.bInterfaceNumber, 0);
-	if (err < 0) {
-		tm6000_err("failed to select interface %d, alt. setting 0\n",
-				dev->isoc_in.bInterfaceNumber);
-		return err;
-	}
-
-	err = usb_reset_configuration(dev->udev);
-	if (err < 0) {
-		tm6000_err("failed to reset configuration\n");
-		return err;
-	}
-
-	if ((dev->quirks & TM6000_QUIRK_NO_USB_DELAY) == 0)
-		msleep(5);
-
-	/*
-	 * Not all devices have int_in defined
-	 */
-	if (!dev->int_in.endp)
-		return 0;
-
-	err = usb_set_interface(dev->udev, dev->isoc_in.bInterfaceNumber, 2);
-	if (err < 0) {
-		tm6000_err("failed to select interface %d, alt. setting 2\n",
-				dev->isoc_in.bInterfaceNumber);
-		return err;
-	}
-
-	msleep(5);
-
-	pipe = usb_rcvintpipe(dev->udev,
-			dev->int_in.endp->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
-
-	err = usb_clear_halt(dev->udev, pipe);
-	if (err < 0) {
-		tm6000_err("usb_clear_halt failed: %d\n", err);
-		return err;
-	}
-
-	return 0;
-}
 
 int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate)
 {
@@ -696,11 +649,13 @@
 	if (dev->dev_type == TM6010) {
 		/* Audio crossbar setting, default SIF1 */
 		u8 areg_f0;
+		u8 areg_07 = 0x10;
 
 		switch (dev->rinput.amux) {
 		case TM6000_AMUX_SIF1:
 		case TM6000_AMUX_SIF2:
 			areg_f0 = 0x03;
+			areg_07 = 0x30;
 			break;
 		case TM6000_AMUX_ADC1:
 			areg_f0 = 0x00;
@@ -720,6 +675,9 @@
 		/* Set audio input crossbar */
 		tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
 							areg_f0, 0x0f);
+		/* Mux overflow workaround */
+		tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL,
+			areg_07, 0xf0);
 	} else {
 		u8 areg_eb;
 		/* Audio setting, default LINE1 */
diff --git a/drivers/media/video/tm6000/tm6000-dvb.c b/drivers/media/video/tm6000/tm6000-dvb.c
index 5e6c129..db6a561 100644
--- a/drivers/media/video/tm6000/tm6000-dvb.c
+++ b/drivers/media/video/tm6000/tm6000-dvb.c
@@ -89,9 +89,19 @@
 	int ret;
 	struct tm6000_core *dev = urb->context;
 
-	if (urb->status != 0)
+	switch (urb->status) {
+	case 0:
+	case -ETIMEDOUT:
+		break;
+	case -ENOENT:
+	case -ECONNRESET:
+	case -ESHUTDOWN:
+		return;
+	default:
 		print_err_status(dev, 0, urb->status);
-	else if (urb->actual_length > 0)
+	}
+
+	if (urb->actual_length > 0)
 		dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
 						   urb->actual_length);
 
@@ -151,7 +161,7 @@
 		printk(KERN_ERR "tm6000: pipe resetted\n");
 
 /*	mutex_lock(&tm6000_driver.open_close_mutex); */
-	ret = usb_submit_urb(dvb->bulk_urb, GFP_KERNEL);
+	ret = usb_submit_urb(dvb->bulk_urb, GFP_ATOMIC);
 
 /*	mutex_unlock(&tm6000_driver.open_close_mutex); */
 	if (ret) {
diff --git a/drivers/media/video/tm6000/tm6000-input.c b/drivers/media/video/tm6000/tm6000-input.c
index 405d127..8d92527 100644
--- a/drivers/media/video/tm6000/tm6000-input.c
+++ b/drivers/media/video/tm6000/tm6000-input.c
@@ -31,22 +31,25 @@
 
 static unsigned int ir_debug;
 module_param(ir_debug, int, 0644);
-MODULE_PARM_DESC(ir_debug, "enable debug message [IR]");
+MODULE_PARM_DESC(ir_debug, "debug message level");
 
 static unsigned int enable_ir = 1;
 module_param(enable_ir, int, 0644);
 MODULE_PARM_DESC(enable_ir, "enable ir (default is enable)");
 
-/* number of 50ms for ON-OFF-ON power led */
-/* show IR activity */
-#define PWLED_OFF 2
+static unsigned int ir_clock_mhz = 12;
+module_param(ir_clock_mhz, int, 0644);
+MODULE_PARM_DESC(enable_ir, "ir clock, in MHz");
+
+#define URB_SUBMIT_DELAY	100	/* ms - Delay to submit an URB request on retrial and init */
+#define URB_INT_LED_DELAY	100	/* ms - Delay to turn led on again on int mode */
 
 #undef dprintk
 
-#define dprintk(fmt, arg...) \
-	if (ir_debug) { \
+#define dprintk(level, fmt, arg...) do {\
+	if (ir_debug >= level) \
 		printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
-	}
+	} while (0)
 
 struct tm6000_ir_poll_result {
 	u16 rc_data;
@@ -62,20 +65,15 @@
 	int			polling;
 	struct delayed_work	work;
 	u8			wait:1;
-	u8			key:1;
-	u8			pwled:1;
-	u8			pwledcnt;
+	u8			pwled:2;
+	u8			submit_urb:1;
 	u16			key_addr;
 	struct urb		*int_urb;
-	u8			*urb_data;
-
-	int (*get_key) (struct tm6000_IR *, struct tm6000_ir_poll_result *);
 
 	/* IR device properties */
 	u64			rc_type;
 };
 
-
 void tm6000_ir_wait(struct tm6000_core *dev, u8 state)
 {
 	struct tm6000_IR *ir = dev->ir;
@@ -83,62 +81,84 @@
 	if (!dev->ir)
 		return;
 
+	dprintk(2, "%s: %i\n",__func__, ir->wait);
+
 	if (state)
 		ir->wait = 1;
 	else
 		ir->wait = 0;
 }
 
-
 static int tm6000_ir_config(struct tm6000_IR *ir)
 {
 	struct tm6000_core *dev = ir->dev;
-	u8 buf[10];
-	int rc;
+	u32 pulse = 0, leader = 0;
+
+	dprintk(2, "%s\n",__func__);
+
+	/*
+	 * The IR decoder supports RC-5 or NEC, with a configurable timing.
+	 * The timing configuration there is not that accurate, as it uses
+	 * approximate values. The NEC spec mentions a 562.5 unit period,
+	 * and RC-5 uses a 888.8 period.
+	 * Currently, driver assumes a clock provided by a 12 MHz XTAL, but
+	 * a modprobe parameter can adjust it.
+	 * Adjustments are required for other timings.
+	 * It seems that the 900ms timing for NEC is used to detect a RC-5
+	 * IR, in order to discard such decoding
+	 */
 
 	switch (ir->rc_type) {
 	case RC_TYPE_NEC:
-		/* Setup IR decoder for NEC standard 12MHz system clock */
-		/* IR_LEADER_CNT = 0.9ms             */
-		tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_LEADER1, 0xaa);
-		tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_LEADER0, 0x30);
-		/* IR_PULSE_CNT = 0.7ms              */
-		tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT1, 0x20);
-		tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT0, 0xd0);
-		/* Remote WAKEUP = enable */
-		tm6000_set_reg(dev, TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe);
-		/* IR_WKUP_SEL = Low byte in decoded IR data */
-		tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0xff);
-		/* IR_WKU_ADD code */
-		tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_ADD, 0xff);
-		tm6000_flash_led(dev, 0);
-		msleep(100);
-		tm6000_flash_led(dev, 1);
+		leader = 900;	/* ms */
+		pulse  = 700;	/* ms - the actual value would be 562 */
 		break;
 	default:
-		/* hack */
-		buf[0] = 0xff;
-		buf[1] = 0xff;
-		buf[2] = 0xf2;
-		buf[3] = 0x2b;
-		buf[4] = 0x20;
-		buf[5] = 0x35;
-		buf[6] = 0x60;
-		buf[7] = 0x04;
-		buf[8] = 0xc0;
-		buf[9] = 0x08;
-
-		rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR |
-			USB_RECIP_DEVICE, REQ_00_SET_IR_VALUE, 0, 0, buf, 0x0a);
-		msleep(100);
-
-		if (rc < 0) {
-			printk(KERN_INFO "IR configuration failed");
-			return rc;
-		}
+	case RC_TYPE_RC5:
+		leader = 900;	/* ms - from the NEC decoding */
+		pulse  = 1780;	/* ms - The actual value would be 1776 */
 		break;
 	}
 
+	pulse = ir_clock_mhz * pulse;
+	leader = ir_clock_mhz * leader;
+	if (ir->rc_type == RC_TYPE_NEC)
+		leader = leader | 0x8000;
+
+	dprintk(2, "%s: %s, %d MHz, leader = 0x%04x, pulse = 0x%06x \n",
+		__func__,
+		(ir->rc_type == RC_TYPE_NEC) ? "NEC" : "RC-5",
+		ir_clock_mhz, leader, pulse);
+
+	/* Remote WAKEUP = enable, normal mode, from IR decoder output */
+	tm6000_set_reg(dev, TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe);
+
+	/* Enable IR reception on non-busrt mode */
+	tm6000_set_reg(dev, TM6010_REQ07_RD8_IR, 0x2f);
+
+	/* IR_WKUP_SEL = Low byte in decoded IR data */
+	tm6000_set_reg(dev, TM6010_REQ07_RDA_IR_WAKEUP_SEL, 0xff);
+	/* IR_WKU_ADD code */
+	tm6000_set_reg(dev, TM6010_REQ07_RDB_IR_WAKEUP_ADD, 0xff);
+
+	tm6000_set_reg(dev, TM6010_REQ07_RDC_IR_LEADER1, leader >> 8);
+	tm6000_set_reg(dev, TM6010_REQ07_RDD_IR_LEADER0, leader);
+
+	tm6000_set_reg(dev, TM6010_REQ07_RDE_IR_PULSE_CNT1, pulse >> 8);
+	tm6000_set_reg(dev, TM6010_REQ07_RDF_IR_PULSE_CNT0, pulse);
+
+	if (!ir->polling)
+		tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0);
+	else
+		tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1);
+	msleep(10);
+
+	/* Shows that IR is working via the LED */
+	tm6000_flash_led(dev, 0);
+	msleep(100);
+	tm6000_flash_led(dev, 1);
+	ir->pwled = 1;
+
 	return 0;
 }
 
@@ -146,132 +166,124 @@
 {
 	struct tm6000_core *dev = urb->context;
 	struct tm6000_IR *ir = dev->ir;
+	struct tm6000_ir_poll_result poll_result;
+	char *buf;
 	int rc;
 
-	if (urb->status != 0)
-		printk(KERN_INFO "not ready\n");
-	else if (urb->actual_length > 0) {
-		memcpy(ir->urb_data, urb->transfer_buffer, urb->actual_length);
-
-		dprintk("data %02x %02x %02x %02x\n", ir->urb_data[0],
-			ir->urb_data[1], ir->urb_data[2], ir->urb_data[3]);
-
-		ir->key = 1;
+	dprintk(2, "%s\n",__func__);
+	if (urb->status < 0 || urb->actual_length <= 0) {
+		printk(KERN_INFO "tm6000: IR URB failure: status: %i, length %i\n",
+		       urb->status, urb->actual_length);
+		ir->submit_urb = 1;
+		schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_SUBMIT_DELAY));
+		return;
 	}
+	buf = urb->transfer_buffer;
+
+	if (ir_debug)
+		print_hex_dump(KERN_DEBUG, "tm6000: IR data: ",
+			       DUMP_PREFIX_OFFSET,16, 1,
+			       buf, urb->actual_length, false);
+
+	poll_result.rc_data = buf[0];
+	if (urb->actual_length > 1)
+		poll_result.rc_data |= buf[1] << 8;
+
+	dprintk(1, "%s, scancode: 0x%04x\n",__func__, poll_result.rc_data);
+	rc_keydown(ir->rc, poll_result.rc_data, 0);
 
 	rc = usb_submit_urb(urb, GFP_ATOMIC);
+	/*
+	 * Flash the led. We can't do it here, as it is running on IRQ context.
+	 * So, use the scheduler to do it, in a few ms.
+	 */
+	ir->pwled = 2;
+	schedule_delayed_work(&ir->work, msecs_to_jiffies(10));
 }
 
-static int default_polling_getkey(struct tm6000_IR *ir,
-				struct tm6000_ir_poll_result *poll_result)
+static void tm6000_ir_handle_key(struct work_struct *work)
 {
+	struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work);
 	struct tm6000_core *dev = ir->dev;
+	struct tm6000_ir_poll_result poll_result;
 	int rc;
 	u8 buf[2];
 
-	if (ir->wait && !&dev->int_in)
-		return 0;
+	if (ir->wait)
+		return;
 
-	if (&dev->int_in) {
-		switch (ir->rc_type) {
-		case RC_TYPE_RC5:
-			poll_result->rc_data = ir->urb_data[0];
-			break;
-		case RC_TYPE_NEC:
-			if (ir->urb_data[1] == ((ir->key_addr >> 8) & 0xff)) {
-				poll_result->rc_data = ir->urb_data[0]
-							| ir->urb_data[1] << 8;
-			}
-			break;
-		default:
-			poll_result->rc_data = ir->urb_data[0]
-					| ir->urb_data[1] << 8;
-			break;
+	dprintk(3, "%s\n",__func__);
+
+	rc = tm6000_read_write_usb(dev, USB_DIR_IN |
+		USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		REQ_02_GET_IR_CODE, 0, 0, buf, 2);
+	if (rc < 0)
+		return;
+
+	if (rc > 1)
+		poll_result.rc_data = buf[0] | buf[1] << 8;
+	else
+		poll_result.rc_data = buf[0];
+
+	/* Check if something was read */
+	if ((poll_result.rc_data & 0xff) == 0xff) {
+		if (!ir->pwled) {
+			tm6000_flash_led(dev, 1);
+			ir->pwled = 1;
 		}
-	} else {
-		tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0);
-		msleep(10);
-		tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1);
-		msleep(10);
-
-		if (ir->rc_type == RC_TYPE_RC5) {
-			rc = tm6000_read_write_usb(dev, USB_DIR_IN |
-				USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-				REQ_02_GET_IR_CODE, 0, 0, buf, 1);
-
-			msleep(10);
-
-			dprintk("read data=%02x\n", buf[0]);
-			if (rc < 0)
-				return rc;
-
-			poll_result->rc_data = buf[0];
-		} else {
-			rc = tm6000_read_write_usb(dev, USB_DIR_IN |
-				USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-				REQ_02_GET_IR_CODE, 0, 0, buf, 2);
-
-			msleep(10);
-
-			dprintk("read data=%04x\n", buf[0] | buf[1] << 8);
-			if (rc < 0)
-				return rc;
-
-			poll_result->rc_data = buf[0] | buf[1] << 8;
-		}
-		if ((poll_result->rc_data & 0x00ff) != 0xff)
-			ir->key = 1;
-	}
-	return 0;
-}
-
-static void tm6000_ir_handle_key(struct tm6000_IR *ir)
-{
-	struct tm6000_core *dev = ir->dev;
-	int result;
-	struct tm6000_ir_poll_result poll_result;
-
-	/* read the registers containing the IR status */
-	result = ir->get_key(ir, &poll_result);
-	if (result < 0) {
-		printk(KERN_INFO "ir->get_key() failed %d\n", result);
 		return;
 	}
 
-	dprintk("ir->get_key result data=%04x\n", poll_result.rc_data);
+	dprintk(1, "%s, scancode: 0x%04x\n",__func__, poll_result.rc_data);
+	rc_keydown(ir->rc, poll_result.rc_data, 0);
+	tm6000_flash_led(dev, 0);
+	ir->pwled = 0;
 
-	if (ir->pwled) {
-		if (ir->pwledcnt >= PWLED_OFF) {
-			ir->pwled = 0;
-			ir->pwledcnt = 0;
-			tm6000_flash_led(dev, 1);
-		} else
-			ir->pwledcnt += 1;
-	}
-
-	if (ir->key) {
-		rc_keydown(ir->rc, poll_result.rc_data, 0);
-		ir->key = 0;
-		ir->pwled = 1;
-		ir->pwledcnt = 0;
-		tm6000_flash_led(dev, 0);
-	}
-	return;
+	/* Re-schedule polling */
+	schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
 }
 
-static void tm6000_ir_work(struct work_struct *work)
+static void tm6000_ir_int_work(struct work_struct *work)
 {
 	struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work);
+	struct tm6000_core *dev = ir->dev;
+	int rc;
 
-	tm6000_ir_handle_key(ir);
-	schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
+	dprintk(3, "%s, submit_urb = %d, pwled = %d\n",__func__, ir->submit_urb,
+		ir->pwled);
+
+	if (ir->submit_urb) {
+		dprintk(3, "Resubmit urb\n");
+		tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0);
+
+		rc = usb_submit_urb(ir->int_urb, GFP_ATOMIC);
+		if (rc < 0) {
+			printk(KERN_ERR "tm6000: Can't submit an IR interrupt. Error %i\n",
+			       rc);
+			/* Retry in 100 ms */
+			schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_SUBMIT_DELAY));
+			return;
+		}
+		ir->submit_urb = 0;
+	}
+
+	/* Led is enabled only if USB submit doesn't fail */
+	if (ir->pwled == 2) {
+		tm6000_flash_led(dev, 0);
+		ir->pwled = 0;
+		schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_INT_LED_DELAY));
+	} else if (!ir->pwled) {
+		tm6000_flash_led(dev, 1);
+		ir->pwled = 1;
+	}
 }
 
 static int tm6000_ir_start(struct rc_dev *rc)
 {
 	struct tm6000_IR *ir = rc->priv;
 
-	INIT_DELAYED_WORK(&ir->work, tm6000_ir_work);
+	dprintk(2, "%s\n",__func__);
+
 	schedule_delayed_work(&ir->work, 0);
 
 	return 0;
@@ -281,6 +293,8 @@
 {
 	struct tm6000_IR *ir = rc->priv;
 
+	dprintk(2, "%s\n",__func__);
+
 	cancel_delayed_work_sync(&ir->work);
 }
 
@@ -291,10 +305,11 @@
 	if (!ir)
 		return 0;
 
+	dprintk(2, "%s\n",__func__);
+
 	if ((rc->rc_map.scan) && (rc_type == RC_TYPE_NEC))
 		ir->key_addr = ((rc->rc_map.scan[0].scancode >> 8) & 0xffff);
 
-	ir->get_key = default_polling_getkey;
 	ir->rc_type = rc_type;
 
 	tm6000_ir_config(ir);
@@ -302,17 +317,19 @@
 	return 0;
 }
 
-int tm6000_ir_int_start(struct tm6000_core *dev)
+static int __tm6000_ir_int_start(struct rc_dev *rc)
 {
-	struct tm6000_IR *ir = dev->ir;
+	struct tm6000_IR *ir = rc->priv;
+	struct tm6000_core *dev = ir->dev;
 	int pipe, size;
 	int err = -ENOMEM;
 
-
 	if (!ir)
 		return -ENODEV;
 
-	ir->int_urb = usb_alloc_urb(0, GFP_KERNEL);
+	dprintk(2, "%s\n",__func__);
+
+	ir->int_urb = usb_alloc_urb(0, GFP_ATOMIC);
 	if (!ir->int_urb)
 		return -ENOMEM;
 
@@ -321,42 +338,59 @@
 		& USB_ENDPOINT_NUMBER_MASK);
 
 	size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
-	dprintk("IR max size: %d\n", size);
+	dprintk(1, "IR max size: %d\n", size);
 
-	ir->int_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
+	ir->int_urb->transfer_buffer = kzalloc(size, GFP_ATOMIC);
 	if (ir->int_urb->transfer_buffer == NULL) {
 		usb_free_urb(ir->int_urb);
 		return err;
 	}
-	dprintk("int interval: %d\n", dev->int_in.endp->desc.bInterval);
+	dprintk(1, "int interval: %d\n", dev->int_in.endp->desc.bInterval);
+
 	usb_fill_int_urb(ir->int_urb, dev->udev, pipe,
 		ir->int_urb->transfer_buffer, size,
 		tm6000_ir_urb_received, dev,
 		dev->int_in.endp->desc.bInterval);
-	err = usb_submit_urb(ir->int_urb, GFP_KERNEL);
-	if (err) {
-		kfree(ir->int_urb->transfer_buffer);
-		usb_free_urb(ir->int_urb);
-		return err;
-	}
-	ir->urb_data = kzalloc(size, GFP_KERNEL);
+
+	ir->submit_urb = 1;
+	schedule_delayed_work(&ir->work, msecs_to_jiffies(URB_SUBMIT_DELAY));
 
 	return 0;
 }
 
+static void __tm6000_ir_int_stop(struct rc_dev *rc)
+{
+	struct tm6000_IR *ir = rc->priv;
+
+	if (!ir || !ir->int_urb)
+		return;
+
+	dprintk(2, "%s\n",__func__);
+
+	usb_kill_urb(ir->int_urb);
+	kfree(ir->int_urb->transfer_buffer);
+	usb_free_urb(ir->int_urb);
+	ir->int_urb = NULL;
+}
+
+int tm6000_ir_int_start(struct tm6000_core *dev)
+{
+	struct tm6000_IR *ir = dev->ir;
+
+	if (!ir)
+		return 0;
+
+	return __tm6000_ir_int_start(ir->rc);
+}
+
 void tm6000_ir_int_stop(struct tm6000_core *dev)
 {
 	struct tm6000_IR *ir = dev->ir;
 
-	if (!ir)
+	if (!ir || !ir->rc)
 		return;
 
-	usb_kill_urb(ir->int_urb);
-	kfree(ir->int_urb->transfer_buffer);
-	usb_free_urb(ir->int_urb);
-	ir->int_urb = NULL;
-	kfree(ir->urb_data);
-	ir->urb_data = NULL;
+	__tm6000_ir_int_stop(ir->rc);
 }
 
 int tm6000_ir_init(struct tm6000_core *dev)
@@ -374,7 +408,9 @@
 	if (!dev->ir_codes)
 		return 0;
 
-	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
+	dprintk(2, "%s\n",__func__);
+
+	ir = kzalloc(sizeof(*ir), GFP_ATOMIC);
 	rc = rc_allocate_device();
 	if (!ir || !rc)
 		goto out;
@@ -384,19 +420,24 @@
 	dev->ir = ir;
 	ir->rc = rc;
 
-	/* input einrichten */
+	/* input setup */
 	rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC;
+	/* Neded, in order to support NEC remotes with 24 or 32 bits */
+	rc->scanmask = 0xffff;
 	rc->priv = ir;
 	rc->change_protocol = tm6000_ir_change_protocol;
-	rc->open = tm6000_ir_start;
-	rc->close = tm6000_ir_stop;
+	if (dev->int_in.endp) {
+		rc->open    = __tm6000_ir_int_start;
+		rc->close   = __tm6000_ir_int_stop;
+		INIT_DELAYED_WORK(&ir->work, tm6000_ir_int_work);
+	} else {
+		rc->open  = tm6000_ir_start;
+		rc->close = tm6000_ir_stop;
+		ir->polling = 50;
+		INIT_DELAYED_WORK(&ir->work, tm6000_ir_handle_key);
+	}
 	rc->driver_type = RC_DRIVER_SCANCODE;
 
-	ir->polling = 50;
-	ir->pwled = 0;
-	ir->pwledcnt = 0;
-
-
 	snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)",
 						dev->name);
 
@@ -415,15 +456,6 @@
 	rc->driver_name = "tm6000";
 	rc->dev.parent = &dev->udev->dev;
 
-	if (&dev->int_in) {
-		dprintk("IR over int\n");
-
-		err = tm6000_ir_int_start(dev);
-
-		if (err)
-			goto out;
-	}
-
 	/* ir register */
 	err = rc_register_device(rc);
 	if (err)
@@ -447,10 +479,19 @@
 	if (!ir)
 		return 0;
 
+	dprintk(2, "%s\n",__func__);
+
 	rc_unregister_device(ir->rc);
 
-	if (ir->int_urb)
-		tm6000_ir_int_stop(dev);
+	if (!ir->polling)
+		__tm6000_ir_int_stop(ir->rc);
+
+	tm6000_ir_stop(ir->rc);
+
+	/* Turn off the led */
+	tm6000_flash_led(dev, 0);
+	ir->pwled = 0;
+
 
 	kfree(ir);
 	dev->ir = NULL;
diff --git a/drivers/media/video/tm6000/tm6000-regs.h b/drivers/media/video/tm6000/tm6000-regs.h
index 7f491b6..a38c251 100644
--- a/drivers/media/video/tm6000/tm6000-regs.h
+++ b/drivers/media/video/tm6000/tm6000-regs.h
@@ -284,19 +284,19 @@
 /* ONLY for TM6010 */
 #define TM6010_REQ07_RD8_IR				0x07, 0xd8
 /* ONLY for TM6010 */
-#define TM6010_REQ07_RD8_IR_BSIZE			0x07, 0xd9
+#define TM6010_REQ07_RD9_IR_BSIZE			0x07, 0xd9
 /* ONLY for TM6010 */
-#define TM6010_REQ07_RD8_IR_WAKEUP_SEL			0x07, 0xda
+#define TM6010_REQ07_RDA_IR_WAKEUP_SEL			0x07, 0xda
 /* ONLY for TM6010 */
-#define TM6010_REQ07_RD8_IR_WAKEUP_ADD			0x07, 0xdb
+#define TM6010_REQ07_RDB_IR_WAKEUP_ADD			0x07, 0xdb
 /* ONLY for TM6010 */
-#define TM6010_REQ07_RD8_IR_LEADER1			0x07, 0xdc
+#define TM6010_REQ07_RDC_IR_LEADER1			0x07, 0xdc
 /* ONLY for TM6010 */
-#define TM6010_REQ07_RD8_IR_LEADER0			0x07, 0xdd
+#define TM6010_REQ07_RDD_IR_LEADER0			0x07, 0xdd
 /* ONLY for TM6010 */
-#define TM6010_REQ07_RD8_IR_PULSE_CNT1			0x07, 0xde
+#define TM6010_REQ07_RDE_IR_PULSE_CNT1			0x07, 0xde
 /* ONLY for TM6010 */
-#define TM6010_REQ07_RD8_IR_PULSE_CNT0			0x07, 0xdf
+#define TM6010_REQ07_RDF_IR_PULSE_CNT0			0x07, 0xdf
 /* ONLY for TM6010 */
 #define TM6010_REQ07_RE0_DVIDEO_SOURCE			0x07, 0xe0
 /* ONLY for TM6010 */
diff --git a/drivers/media/video/tm6000/tm6000-stds.c b/drivers/media/video/tm6000/tm6000-stds.c
index 9a4145dc..9dc0831 100644
--- a/drivers/media/video/tm6000/tm6000-stds.c
+++ b/drivers/media/video/tm6000/tm6000-stds.c
@@ -361,82 +361,51 @@
 		return 0;
 	}
 
-	switch (tm6010_a_mode) {
+	/*
+	 * STD/MN shouldn't be affected by tm6010_a_mode, as there's just one
+	 * audio standard for each V4L2_STD type.
+	 */
+	if ((dev->norm & V4L2_STD_NTSC) == V4L2_STD_NTSC_M_KR) {
+		areg_05 |= 0x04;
+	} else if ((dev->norm & V4L2_STD_NTSC) == V4L2_STD_NTSC_M_JP) {
+		areg_05 |= 0x43;
+	} else if (dev->norm & V4L2_STD_MN) {
+		areg_05 |= 0x22;
+	} else switch (tm6010_a_mode) {
 	/* auto */
 	case 0:
-		switch (dev->norm) {
-		case V4L2_STD_NTSC_M_KR:
+		if ((dev->norm & V4L2_STD_SECAM) == V4L2_STD_SECAM_L)
 			areg_05 |= 0x00;
-			break;
-		case V4L2_STD_NTSC_M_JP:
-			areg_05 |= 0x40;
-			break;
-		case V4L2_STD_NTSC_M:
-		case V4L2_STD_PAL_M:
-		case V4L2_STD_PAL_N:
-			areg_05 |= 0x20;
-			break;
-		case V4L2_STD_PAL_Nc:
-			areg_05 |= 0x60;
-			break;
-		case V4L2_STD_SECAM_L:
-			areg_05 |= 0x00;
-			break;
-		case V4L2_STD_DK:
+		else	/* Other PAL/SECAM standards */
 			areg_05 |= 0x10;
-			break;
-		}
 		break;
 	/* A2 */
 	case 1:
-		switch (dev->norm) {
-		case V4L2_STD_B:
-		case V4L2_STD_GH:
-			areg_05 = 0x05;
-			break;
-		case V4L2_STD_DK:
+		if (dev->norm & V4L2_STD_DK)
 			areg_05 = 0x09;
-			break;
-		}
+		else
+			areg_05 = 0x05;
 		break;
 	/* NICAM */
 	case 2:
-		switch (dev->norm) {
-		case V4L2_STD_B:
-		case V4L2_STD_GH:
-			areg_05 = 0x07;
-			break;
-		case V4L2_STD_DK:
+		if (dev->norm & V4L2_STD_DK) {
 			areg_05 = 0x06;
-			break;
-		case V4L2_STD_PAL_I:
+		} else if (dev->norm & V4L2_STD_PAL_I) {
 			areg_05 = 0x08;
-			break;
-		case V4L2_STD_SECAM_L:
+		} else if (dev->norm & V4L2_STD_SECAM_L) {
 			areg_05 = 0x0a;
 			areg_02 = 0x02;
-			break;
+		} else {
+			areg_05 = 0x07;
 		}
 		nicam_flag = 1;
 		break;
 	/* other */
 	case 3:
-		switch (dev->norm) {
-		/* DK3_A2 */
-		case V4L2_STD_DK:
+		if (dev->norm & V4L2_STD_DK) {
 			areg_05 = 0x0b;
-			break;
-		/* Korea */
-		case V4L2_STD_NTSC_M_KR:
-			areg_05 = 0x04;
-			break;
-		/* EIAJ */
-		case V4L2_STD_NTSC_M_JP:
-			areg_05 = 0x03;
-			break;
-		default:
+		} else {
 			areg_05 = 0x02;
-			break;
 		}
 		break;
 	}
@@ -557,10 +526,16 @@
 		case TM6000_AMUX_ADC1:
 			tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
 				0x00, 0x0f);
+			/* Mux overflow workaround */
+			tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL,
+				0x10, 0xf0);
 			break;
 		case TM6000_AMUX_ADC2:
 			tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
 				0x08, 0x0f);
+			/* Mux overflow workaround */
+			tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL,
+				0x10, 0xf0);
 			break;
 		case TM6000_AMUX_SIF1:
 			reg_08_e2 |= 0x02;
@@ -570,6 +545,9 @@
 			tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3);
 			tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
 				0x02, 0x0f);
+			/* Mux overflow workaround */
+			tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL,
+				0x30, 0xf0);
 			break;
 		case TM6000_AMUX_SIF2:
 			reg_08_e2 |= 0x02;
@@ -579,6 +557,9 @@
 			tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf7);
 			tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
 				0x02, 0x0f);
+			/* Mux overflow workaround */
+			tm6000_set_reg_mask(dev, TM6010_REQ07_R07_OUTPUT_CONTROL,
+				0x30, 0xf0);
 			break;
 		default:
 			break;
diff --git a/drivers/media/video/tm6000/tm6000-video.c b/drivers/media/video/tm6000/tm6000-video.c
index 1e5ace0..bc13db7 100644
--- a/drivers/media/video/tm6000/tm6000-video.c
+++ b/drivers/media/video/tm6000/tm6000-video.c
@@ -1605,16 +1605,25 @@
 	res_free(dev, fh);
 
 	if (!dev->users) {
-		int err;
-
 		tm6000_uninit_isoc(dev);
 
+		/* Stop interrupt USB pipe */
+		tm6000_ir_int_stop(dev);
+
+		usb_reset_configuration(dev->udev);
+
+		if (dev->int_in.endp)
+			usb_set_interface(dev->udev,
+					dev->isoc_in.bInterfaceNumber, 2);
+		else
+			usb_set_interface(dev->udev,
+					dev->isoc_in.bInterfaceNumber, 0);
+
+		/* Start interrupt USB pipe */
+		tm6000_ir_int_start(dev);
+
 		if (!fh->radio)
 			videobuf_mmap_free(&fh->vb_vidq);
-
-		err = tm6000_reset(dev);
-		if (err < 0)
-			dev_err(&vdev->dev, "reset failed: %d\n", err);
 	}
 
 	kfree(fh);
diff --git a/drivers/media/video/tm6000/tm6000.h b/drivers/media/video/tm6000/tm6000.h
index 2777e51..27ba659 100644
--- a/drivers/media/video/tm6000/tm6000.h
+++ b/drivers/media/video/tm6000/tm6000.h
@@ -188,6 +188,9 @@
 	/* Device Capabilities*/
 	struct tm6000_capabilities	caps;
 
+	/* Used to load alsa/dvb */
+        struct work_struct		request_module_wk;
+
 	/* Tuner configuration */
 	int				tuner_type;		/* type of the tuner */
 	int				tuner_addr;		/* tuner address */
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 6abaa16..fc91a1e 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -703,21 +703,21 @@
 	/* First tests should be against specific std */
 
 	if (std == V4L2_STD_ALL) {
-		fmt = 0;	/* Autodetect mode */
+		fmt = VIDEO_STD_AUTO_SWITCH_BIT;	/* Autodetect mode */
 	} else if (std & V4L2_STD_NTSC_443) {
-		fmt = 0xa;
+		fmt = VIDEO_STD_NTSC_4_43_BIT;
 	} else if (std & V4L2_STD_PAL_M) {
-		fmt = 0x6;
+		fmt = VIDEO_STD_PAL_M_BIT;
 	} else if (std & (V4L2_STD_PAL_N | V4L2_STD_PAL_Nc)) {
-		fmt = 0x8;
+		fmt = VIDEO_STD_PAL_COMBINATION_N_BIT;
 	} else {
 		/* Then, test against generic ones */
 		if (std & V4L2_STD_NTSC)
-			fmt = 0x2;
+			fmt = VIDEO_STD_NTSC_MJ_BIT;
 		else if (std & V4L2_STD_PAL)
-			fmt = 0x4;
+			fmt = VIDEO_STD_PAL_BDGHIN_BIT;
 		else if (std & V4L2_STD_SECAM)
-			fmt = 0xc;
+			fmt = VIDEO_STD_SECAM_BIT;
 	}
 
 	v4l2_dbg(1, debug, sd, "Set video std register to %d.\n", fmt);
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index d7f9751..89fec02 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -110,42 +110,20 @@
 
 	unsigned char addr;
 	int ret;
-	if ((flags & I2C_M_TEN)) {
-		/* a ten bit address */
-		addr = 0xf0 | ((msg->addr >> 7) & 0x03);
-		/* try extended address code... */
+
+	addr = (msg->addr << 1);
+	if (flags & I2C_M_RD)
+		addr |= 1;
+
+	add[0] = addr;
+	if (flags & I2C_M_RD)
+		ret = try_read_address(i2c_adap, addr, retries);
+	else
 		ret = try_write_address(i2c_adap, addr, retries);
-		if (ret != 1) {
-			dev_err(&i2c_adap->dev,
-				"died at extended address code,	while writing\n");
-			return -EREMOTEIO;
-		}
-		add[0] = addr;
-		if (flags & I2C_M_RD) {
-			/* okay, now switch into reading mode */
-			addr |= 0x01;
-			ret = try_read_address(i2c_adap, addr, retries);
-			if (ret != 1) {
-				dev_err(&i2c_adap->dev,
-					"died at extended address code, while reading\n");
-				return -EREMOTEIO;
-			}
-		}
 
-	} else {		/* normal 7bit address  */
-		addr = (msg->addr << 1);
-		if (flags & I2C_M_RD)
-			addr |= 1;
+	if (ret != 1)
+		return -EREMOTEIO;
 
-		add[0] = addr;
-		if (flags & I2C_M_RD)
-			ret = try_read_address(i2c_adap, addr, retries);
-		else
-			ret = try_write_address(i2c_adap, addr, retries);
-
-		if (ret != 1)
-			return -EREMOTEIO;
-	}
 	return 0;
 }
 
@@ -184,7 +162,7 @@
 
 static u32 functionality(struct i2c_adapter *adap)
 {
-	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
 }
 
 /* -----exported algorithm data: -------------------------------------	*/
diff --git a/drivers/media/video/uvc/Kconfig b/drivers/media/video/uvc/Kconfig
index 2956a76..6c197da 100644
--- a/drivers/media/video/uvc/Kconfig
+++ b/drivers/media/video/uvc/Kconfig
@@ -1,5 +1,6 @@
 config USB_VIDEO_CLASS
 	tristate "USB Video Class (UVC)"
+	select VIDEOBUF2_VMALLOC
 	---help---
 	  Support for the USB Video Class (UVC).  Currently only video
 	  input devices, such as webcams, are supported.
diff --git a/drivers/media/video/uvc/Makefile b/drivers/media/video/uvc/Makefile
index 2071ca8..c26d12f 100644
--- a/drivers/media/video/uvc/Makefile
+++ b/drivers/media/video/uvc/Makefile
@@ -1,5 +1,5 @@
 uvcvideo-objs  := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o \
-		  uvc_status.o uvc_isight.o
+		  uvc_status.o uvc_isight.o uvc_debugfs.o
 ifeq ($(CONFIG_MEDIA_CONTROLLER),y)
 uvcvideo-objs  += uvc_entity.o
 endif
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 254d326..3e849d9 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -878,8 +878,21 @@
 				     chain->dev->intfnum, ctrl->info.selector,
 				     uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES),
 				     ctrl->info.size);
-		if (ret < 0)
-			return ret;
+		if (ret < 0) {
+			if (UVC_ENTITY_TYPE(ctrl->entity) !=
+			    UVC_VC_EXTENSION_UNIT)
+				return ret;
+
+			/* GET_RES is mandatory for XU controls, but some
+			 * cameras still choke on it. Ignore errors and set the
+			 * resolution value to zero.
+			 */
+			uvc_warn_once(chain->dev, UVC_WARN_XU_GET_RES,
+				      "UVC non compliance - GET_RES failed on "
+				      "an XU control. Enabling workaround.\n");
+			memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES), 0,
+			       ctrl->info.size);
+		}
 	}
 
 	ctrl->cached = 1;
diff --git a/drivers/media/video/uvc/uvc_debugfs.c b/drivers/media/video/uvc/uvc_debugfs.c
new file mode 100644
index 0000000..14561a5
--- /dev/null
+++ b/drivers/media/video/uvc/uvc_debugfs.c
@@ -0,0 +1,136 @@
+/*
+ *      uvc_debugfs.c --  USB Video Class driver - Debugging support
+ *
+ *      Copyright (C) 2011
+ *          Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+
+#include "uvcvideo.h"
+
+/* -----------------------------------------------------------------------------
+ * Statistics
+ */
+
+#define UVC_DEBUGFS_BUF_SIZE	1024
+
+struct uvc_debugfs_buffer {
+	size_t count;
+	char data[UVC_DEBUGFS_BUF_SIZE];
+};
+
+static int uvc_debugfs_stats_open(struct inode *inode, struct file *file)
+{
+	struct uvc_streaming *stream = inode->i_private;
+	struct uvc_debugfs_buffer *buf;
+
+	buf = kmalloc(sizeof(*buf), GFP_KERNEL);
+	if (buf == NULL)
+		return -ENOMEM;
+
+	buf->count = uvc_video_stats_dump(stream, buf->data, sizeof(buf->data));
+
+	file->private_data = buf;
+	return 0;
+}
+
+static ssize_t uvc_debugfs_stats_read(struct file *file, char __user *user_buf,
+				      size_t nbytes, loff_t *ppos)
+{
+	struct uvc_debugfs_buffer *buf = file->private_data;
+
+	return simple_read_from_buffer(user_buf, nbytes, ppos, buf->data,
+				       buf->count);
+}
+
+static int uvc_debugfs_stats_release(struct inode *inode, struct file *file)
+{
+	kfree(file->private_data);
+	file->private_data = NULL;
+
+	return 0;
+}
+
+static const struct file_operations uvc_debugfs_stats_fops = {
+	.owner = THIS_MODULE,
+	.open = uvc_debugfs_stats_open,
+	.llseek = no_llseek,
+	.read = uvc_debugfs_stats_read,
+	.release = uvc_debugfs_stats_release,
+};
+
+/* -----------------------------------------------------------------------------
+ * Global and stream initialization/cleanup
+ */
+
+static struct dentry *uvc_debugfs_root_dir;
+
+int uvc_debugfs_init_stream(struct uvc_streaming *stream)
+{
+	struct usb_device *udev = stream->dev->udev;
+	struct dentry *dent;
+	char dir_name[32];
+
+	if (uvc_debugfs_root_dir == NULL)
+		return -ENODEV;
+
+	sprintf(dir_name, "%u-%u", udev->bus->busnum, udev->devnum);
+
+	dent = debugfs_create_dir(dir_name, uvc_debugfs_root_dir);
+	if (IS_ERR_OR_NULL(dent)) {
+		uvc_printk(KERN_INFO, "Unable to create debugfs %s "
+			   "directory.\n", dir_name);
+		return -ENODEV;
+	}
+
+	stream->debugfs_dir = dent;
+
+	dent = debugfs_create_file("stats", 0444, stream->debugfs_dir,
+				   stream, &uvc_debugfs_stats_fops);
+	if (IS_ERR_OR_NULL(dent)) {
+		uvc_printk(KERN_INFO, "Unable to create debugfs stats file.\n");
+		uvc_debugfs_cleanup_stream(stream);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+void uvc_debugfs_cleanup_stream(struct uvc_streaming *stream)
+{
+	if (stream->debugfs_dir == NULL)
+		return;
+
+	debugfs_remove_recursive(stream->debugfs_dir);
+	stream->debugfs_dir = NULL;
+}
+
+int uvc_debugfs_init(void)
+{
+	struct dentry *dir;
+
+	dir = debugfs_create_dir("uvcvideo", usb_debug_root);
+	if (IS_ERR_OR_NULL(dir)) {
+		uvc_printk(KERN_INFO, "Unable to create debugfs directory\n");
+		return -ENODATA;
+	}
+
+	uvc_debugfs_root_dir = dir;
+	return 0;
+}
+
+void uvc_debugfs_cleanup(void)
+{
+	if (uvc_debugfs_root_dir != NULL)
+		debugfs_remove_recursive(uvc_debugfs_root_dir);
+}
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 656d4c9..a240d43 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1675,6 +1675,8 @@
 
 		video_unregister_device(stream->vdev);
 		stream->vdev = NULL;
+
+		uvc_debugfs_cleanup_stream(stream);
 	}
 
 	/* Decrement the stream count and call uvc_delete explicitly if there
@@ -1700,6 +1702,8 @@
 		return ret;
 	}
 
+	uvc_debugfs_init_stream(stream);
+
 	/* Register the device with V4L. */
 	vdev = video_device_alloc();
 	if (vdev == NULL) {
@@ -2033,6 +2037,15 @@
  * though they are compliant.
  */
 static struct usb_device_id uvc_ids[] = {
+	/* LogiLink Wireless Webcam */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x0416,
+	  .idProduct		= 0xa91a,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
 	/* Genius eFace 2025 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2396,17 +2409,24 @@
 
 static int __init uvc_init(void)
 {
-	int result;
+	int ret;
 
-	result = usb_register(&uvc_driver.driver);
-	if (result == 0)
-		printk(KERN_INFO DRIVER_DESC " (" DRIVER_VERSION ")\n");
-	return result;
+	uvc_debugfs_init();
+
+	ret = usb_register(&uvc_driver.driver);
+	if (ret < 0) {
+		uvc_debugfs_cleanup();
+		return ret;
+	}
+
+	printk(KERN_INFO DRIVER_DESC " (" DRIVER_VERSION ")\n");
+	return 0;
 }
 
 static void __exit uvc_cleanup(void)
 {
 	usb_deregister(&uvc_driver.driver);
+	uvc_debugfs_cleanup();
 }
 
 module_init(uvc_init);
diff --git a/drivers/media/video/uvc/uvc_isight.c b/drivers/media/video/uvc/uvc_isight.c
index 74bbe8f..8510e725 100644
--- a/drivers/media/video/uvc/uvc_isight.c
+++ b/drivers/media/video/uvc/uvc_isight.c
@@ -74,7 +74,7 @@
 	 * Empty buffers (bytesused == 0) don't trigger end of frame detection
 	 * as it doesn't make sense to return an empty buffer.
 	 */
-	if (is_header && buf->buf.bytesused != 0) {
+	if (is_header && buf->bytesused != 0) {
 		buf->state = UVC_BUF_STATE_DONE;
 		return -EAGAIN;
 	}
@@ -83,13 +83,13 @@
 	 * contain no data.
 	 */
 	if (!is_header) {
-		maxlen = buf->buf.length - buf->buf.bytesused;
-		mem = queue->mem + buf->buf.m.offset + buf->buf.bytesused;
+		maxlen = buf->length - buf->bytesused;
+		mem = buf->mem + buf->bytesused;
 		nbytes = min(len, maxlen);
 		memcpy(mem, data, nbytes);
-		buf->buf.bytesused += nbytes;
+		buf->bytesused += nbytes;
 
-		if (len > maxlen || buf->buf.bytesused == buf->buf.length) {
+		if (len > maxlen || buf->bytesused == buf->length) {
 			uvc_trace(UVC_TRACE_FRAME, "Frame complete "
 				  "(overflow).\n");
 			buf->state = UVC_BUF_STATE_DONE;
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index 677691c..518f77d 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -11,6 +11,7 @@
  *
  */
 
+#include <linux/atomic.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/list.h>
@@ -19,7 +20,7 @@
 #include <linux/videodev2.h>
 #include <linux/vmalloc.h>
 #include <linux/wait.h>
-#include <linux/atomic.h>
+#include <media/videobuf2-vmalloc.h>
 
 #include "uvcvideo.h"
 
@@ -29,163 +30,199 @@
  * Video queues is initialized by uvc_queue_init(). The function performs
  * basic initialization of the uvc_video_queue struct and never fails.
  *
- * Video buffer allocation and freeing are performed by uvc_alloc_buffers and
- * uvc_free_buffers respectively. The former acquires the video queue lock,
- * while the later must be called with the lock held (so that allocation can
- * free previously allocated buffers). Trying to free buffers that are mapped
- * to user space will return -EBUSY.
- *
- * Video buffers are managed using two queues. However, unlike most USB video
- * drivers that use an in queue and an out queue, we use a main queue to hold
- * all queued buffers (both 'empty' and 'done' buffers), and an irq queue to
- * hold empty buffers. This design (copied from video-buf) minimizes locking
- * in interrupt, as only one queue is shared between interrupt and user
- * contexts.
- *
- * Use cases
- * ---------
- *
- * Unless stated otherwise, all operations that modify the irq buffers queue
- * are protected by the irq spinlock.
- *
- * 1. The user queues the buffers, starts streaming and dequeues a buffer.
- *
- *    The buffers are added to the main and irq queues. Both operations are
- *    protected by the queue lock, and the later is protected by the irq
- *    spinlock as well.
- *
- *    The completion handler fetches a buffer from the irq queue and fills it
- *    with video data. If no buffer is available (irq queue empty), the handler
- *    returns immediately.
- *
- *    When the buffer is full, the completion handler removes it from the irq
- *    queue, marks it as done (UVC_BUF_STATE_DONE) and wakes its wait queue.
- *    At that point, any process waiting on the buffer will be woken up. If a
- *    process tries to dequeue a buffer after it has been marked done, the
- *    dequeing will succeed immediately.
- *
- * 2. Buffers are queued, user is waiting on a buffer and the device gets
- *    disconnected.
- *
- *    When the device is disconnected, the kernel calls the completion handler
- *    with an appropriate status code. The handler marks all buffers in the
- *    irq queue as being erroneous (UVC_BUF_STATE_ERROR) and wakes them up so
- *    that any process waiting on a buffer gets woken up.
- *
- *    Waking up up the first buffer on the irq list is not enough, as the
- *    process waiting on the buffer might restart the dequeue operation
- *    immediately.
- *
+ * Video buffers are managed by videobuf2. The driver uses a mutex to protect
+ * the videobuf2 queue operations by serializing calls to videobuf2 and a
+ * spinlock to protect the IRQ queue that holds the buffers to be processed by
+ * the driver.
  */
 
-void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
-		    int drop_corrupted)
-{
-	mutex_init(&queue->mutex);
-	spin_lock_init(&queue->irqlock);
-	INIT_LIST_HEAD(&queue->mainqueue);
-	INIT_LIST_HEAD(&queue->irqqueue);
-	queue->flags = drop_corrupted ? UVC_QUEUE_DROP_CORRUPTED : 0;
-	queue->type = type;
-}
-
-/*
- * Free the video buffers.
- *
- * This function must be called with the queue lock held.
+/* -----------------------------------------------------------------------------
+ * videobuf2 queue operations
  */
-static int __uvc_free_buffers(struct uvc_video_queue *queue)
+
+static int uvc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
+			   unsigned int *nbuffers, unsigned int *nplanes,
+			   unsigned int sizes[], void *alloc_ctxs[])
 {
-	unsigned int i;
+	struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
+	struct uvc_streaming *stream =
+			container_of(queue, struct uvc_streaming, queue);
 
-	for (i = 0; i < queue->count; ++i) {
-		if (queue->buffer[i].vma_use_count != 0)
-			return -EBUSY;
-	}
+	if (*nbuffers > UVC_MAX_VIDEO_BUFFERS)
+		*nbuffers = UVC_MAX_VIDEO_BUFFERS;
 
-	if (queue->count) {
-		uvc_queue_cancel(queue, 0);
-		INIT_LIST_HEAD(&queue->mainqueue);
-		vfree(queue->mem);
-		queue->count = 0;
-	}
+	*nplanes = 1;
+
+	sizes[0] = stream->ctrl.dwMaxVideoFrameSize;
 
 	return 0;
 }
 
-int uvc_free_buffers(struct uvc_video_queue *queue)
+static int uvc_buffer_prepare(struct vb2_buffer *vb)
 {
-	int ret;
+	struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
+	struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf);
 
-	mutex_lock(&queue->mutex);
-	ret = __uvc_free_buffers(queue);
-	mutex_unlock(&queue->mutex);
+	if (vb->v4l2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+	    vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) {
+		uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n");
+		return -EINVAL;
+	}
 
-	return ret;
+	if (unlikely(queue->flags & UVC_QUEUE_DISCONNECTED))
+		return -ENODEV;
+
+	buf->state = UVC_BUF_STATE_QUEUED;
+	buf->error = 0;
+	buf->mem = vb2_plane_vaddr(vb, 0);
+	buf->length = vb2_plane_size(vb, 0);
+	if (vb->v4l2_buf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		buf->bytesused = 0;
+	else
+		buf->bytesused = vb2_get_plane_payload(vb, 0);
+
+	return 0;
 }
 
-/*
- * Allocate the video buffers.
- *
- * Pages are reserved to make sure they will not be swapped, as they will be
- * filled in the URB completion handler.
- *
- * Buffers will be individually mapped, so they must all be page aligned.
+static void uvc_buffer_queue(struct vb2_buffer *vb)
+{
+	struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
+	struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf);
+	unsigned long flags;
+
+	spin_lock_irqsave(&queue->irqlock, flags);
+	if (likely(!(queue->flags & UVC_QUEUE_DISCONNECTED))) {
+		list_add_tail(&buf->queue, &queue->irqqueue);
+	} else {
+		/* If the device is disconnected return the buffer to userspace
+		 * directly. The next QBUF call will fail with -ENODEV.
+		 */
+		buf->state = UVC_BUF_STATE_ERROR;
+		vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR);
+	}
+
+	spin_unlock_irqrestore(&queue->irqlock, flags);
+}
+
+static int uvc_buffer_finish(struct vb2_buffer *vb)
+{
+	struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue);
+	struct uvc_streaming *stream =
+			container_of(queue, struct uvc_streaming, queue);
+	struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf);
+
+	uvc_video_clock_update(stream, &vb->v4l2_buf, buf);
+	return 0;
+}
+
+static struct vb2_ops uvc_queue_qops = {
+	.queue_setup = uvc_queue_setup,
+	.buf_prepare = uvc_buffer_prepare,
+	.buf_queue = uvc_buffer_queue,
+	.buf_finish = uvc_buffer_finish,
+};
+
+void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
+		    int drop_corrupted)
+{
+	queue->queue.type = type;
+	queue->queue.io_modes = VB2_MMAP;
+	queue->queue.drv_priv = queue;
+	queue->queue.buf_struct_size = sizeof(struct uvc_buffer);
+	queue->queue.ops = &uvc_queue_qops;
+	queue->queue.mem_ops = &vb2_vmalloc_memops;
+	vb2_queue_init(&queue->queue);
+
+	mutex_init(&queue->mutex);
+	spin_lock_init(&queue->irqlock);
+	INIT_LIST_HEAD(&queue->irqqueue);
+	queue->flags = drop_corrupted ? UVC_QUEUE_DROP_CORRUPTED : 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 queue operations
  */
-int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers,
-		unsigned int buflength)
+
+int uvc_alloc_buffers(struct uvc_video_queue *queue,
+		      struct v4l2_requestbuffers *rb)
 {
-	unsigned int bufsize = PAGE_ALIGN(buflength);
-	unsigned int i;
-	void *mem = NULL;
 	int ret;
 
-	if (nbuffers > UVC_MAX_VIDEO_BUFFERS)
-		nbuffers = UVC_MAX_VIDEO_BUFFERS;
+	mutex_lock(&queue->mutex);
+	ret = vb2_reqbufs(&queue->queue, rb);
+	mutex_unlock(&queue->mutex);
+
+	return ret ? ret : rb->count;
+}
+
+void uvc_free_buffers(struct uvc_video_queue *queue)
+{
+	mutex_lock(&queue->mutex);
+	vb2_queue_release(&queue->queue);
+	mutex_unlock(&queue->mutex);
+}
+
+int uvc_query_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf)
+{
+	int ret;
 
 	mutex_lock(&queue->mutex);
-
-	if ((ret = __uvc_free_buffers(queue)) < 0)
-		goto done;
-
-	/* Bail out if no buffers should be allocated. */
-	if (nbuffers == 0)
-		goto done;
-
-	/* Decrement the number of buffers until allocation succeeds. */
-	for (; nbuffers > 0; --nbuffers) {
-		mem = vmalloc_32(nbuffers * bufsize);
-		if (mem != NULL)
-			break;
-	}
-
-	if (mem == NULL) {
-		ret = -ENOMEM;
-		goto done;
-	}
-
-	for (i = 0; i < nbuffers; ++i) {
-		memset(&queue->buffer[i], 0, sizeof queue->buffer[i]);
-		queue->buffer[i].buf.index = i;
-		queue->buffer[i].buf.m.offset = i * bufsize;
-		queue->buffer[i].buf.length = buflength;
-		queue->buffer[i].buf.type = queue->type;
-		queue->buffer[i].buf.field = V4L2_FIELD_NONE;
-		queue->buffer[i].buf.memory = V4L2_MEMORY_MMAP;
-		queue->buffer[i].buf.flags = 0;
-		init_waitqueue_head(&queue->buffer[i].wait);
-	}
-
-	queue->mem = mem;
-	queue->count = nbuffers;
-	queue->buf_size = bufsize;
-	ret = nbuffers;
-
-done:
+	ret = vb2_querybuf(&queue->queue, buf);
 	mutex_unlock(&queue->mutex);
+
 	return ret;
 }
 
+int uvc_queue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf)
+{
+	int ret;
+
+	mutex_lock(&queue->mutex);
+	ret = vb2_qbuf(&queue->queue, buf);
+	mutex_unlock(&queue->mutex);
+
+	return ret;
+}
+
+int uvc_dequeue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf,
+		       int nonblocking)
+{
+	int ret;
+
+	mutex_lock(&queue->mutex);
+	ret = vb2_dqbuf(&queue->queue, buf, nonblocking);
+	mutex_unlock(&queue->mutex);
+
+	return ret;
+}
+
+int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
+{
+	int ret;
+
+	mutex_lock(&queue->mutex);
+	ret = vb2_mmap(&queue->queue, vma);
+	mutex_unlock(&queue->mutex);
+
+	return ret;
+}
+
+unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file,
+			    poll_table *wait)
+{
+	unsigned int ret;
+
+	mutex_lock(&queue->mutex);
+	ret = vb2_poll(&queue->queue, file, wait);
+	mutex_unlock(&queue->mutex);
+
+	return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ *
+ */
+
 /*
  * Check if buffers have been allocated.
  */
@@ -194,304 +231,12 @@
 	int allocated;
 
 	mutex_lock(&queue->mutex);
-	allocated = queue->count != 0;
+	allocated = vb2_is_busy(&queue->queue);
 	mutex_unlock(&queue->mutex);
 
 	return allocated;
 }
 
-static void __uvc_query_buffer(struct uvc_buffer *buf,
-		struct v4l2_buffer *v4l2_buf)
-{
-	memcpy(v4l2_buf, &buf->buf, sizeof *v4l2_buf);
-
-	if (buf->vma_use_count)
-		v4l2_buf->flags |= V4L2_BUF_FLAG_MAPPED;
-
-	switch (buf->state) {
-	case UVC_BUF_STATE_ERROR:
-	case UVC_BUF_STATE_DONE:
-		v4l2_buf->flags |= V4L2_BUF_FLAG_DONE;
-		break;
-	case UVC_BUF_STATE_QUEUED:
-	case UVC_BUF_STATE_ACTIVE:
-	case UVC_BUF_STATE_READY:
-		v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED;
-		break;
-	case UVC_BUF_STATE_IDLE:
-	default:
-		break;
-	}
-}
-
-int uvc_query_buffer(struct uvc_video_queue *queue,
-		struct v4l2_buffer *v4l2_buf)
-{
-	int ret = 0;
-
-	mutex_lock(&queue->mutex);
-	if (v4l2_buf->index >= queue->count) {
-		ret = -EINVAL;
-		goto done;
-	}
-
-	__uvc_query_buffer(&queue->buffer[v4l2_buf->index], v4l2_buf);
-
-done:
-	mutex_unlock(&queue->mutex);
-	return ret;
-}
-
-/*
- * Queue a video buffer. Attempting to queue a buffer that has already been
- * queued will return -EINVAL.
- */
-int uvc_queue_buffer(struct uvc_video_queue *queue,
-	struct v4l2_buffer *v4l2_buf)
-{
-	struct uvc_buffer *buf;
-	unsigned long flags;
-	int ret = 0;
-
-	uvc_trace(UVC_TRACE_CAPTURE, "Queuing buffer %u.\n", v4l2_buf->index);
-
-	if (v4l2_buf->type != queue->type ||
-	    v4l2_buf->memory != V4L2_MEMORY_MMAP) {
-		uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) "
-			"and/or memory (%u).\n", v4l2_buf->type,
-			v4l2_buf->memory);
-		return -EINVAL;
-	}
-
-	mutex_lock(&queue->mutex);
-	if (v4l2_buf->index >= queue->count) {
-		uvc_trace(UVC_TRACE_CAPTURE, "[E] Out of range index.\n");
-		ret = -EINVAL;
-		goto done;
-	}
-
-	buf = &queue->buffer[v4l2_buf->index];
-	if (buf->state != UVC_BUF_STATE_IDLE) {
-		uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state "
-			"(%u).\n", buf->state);
-		ret = -EINVAL;
-		goto done;
-	}
-
-	if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
-	    v4l2_buf->bytesused > buf->buf.length) {
-		uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n");
-		ret = -EINVAL;
-		goto done;
-	}
-
-	spin_lock_irqsave(&queue->irqlock, flags);
-	if (queue->flags & UVC_QUEUE_DISCONNECTED) {
-		spin_unlock_irqrestore(&queue->irqlock, flags);
-		ret = -ENODEV;
-		goto done;
-	}
-	buf->state = UVC_BUF_STATE_QUEUED;
-	if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		buf->buf.bytesused = 0;
-	else
-		buf->buf.bytesused = v4l2_buf->bytesused;
-
-	list_add_tail(&buf->stream, &queue->mainqueue);
-	list_add_tail(&buf->queue, &queue->irqqueue);
-	spin_unlock_irqrestore(&queue->irqlock, flags);
-
-done:
-	mutex_unlock(&queue->mutex);
-	return ret;
-}
-
-static int uvc_queue_waiton(struct uvc_buffer *buf, int nonblocking)
-{
-	if (nonblocking) {
-		return (buf->state != UVC_BUF_STATE_QUEUED &&
-			buf->state != UVC_BUF_STATE_ACTIVE &&
-			buf->state != UVC_BUF_STATE_READY)
-			? 0 : -EAGAIN;
-	}
-
-	return wait_event_interruptible(buf->wait,
-		buf->state != UVC_BUF_STATE_QUEUED &&
-		buf->state != UVC_BUF_STATE_ACTIVE &&
-		buf->state != UVC_BUF_STATE_READY);
-}
-
-/*
- * Dequeue a video buffer. If nonblocking is false, block until a buffer is
- * available.
- */
-int uvc_dequeue_buffer(struct uvc_video_queue *queue,
-		struct v4l2_buffer *v4l2_buf, int nonblocking)
-{
-	struct uvc_buffer *buf;
-	int ret = 0;
-
-	if (v4l2_buf->type != queue->type ||
-	    v4l2_buf->memory != V4L2_MEMORY_MMAP) {
-		uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer type (%u) "
-			"and/or memory (%u).\n", v4l2_buf->type,
-			v4l2_buf->memory);
-		return -EINVAL;
-	}
-
-	mutex_lock(&queue->mutex);
-	if (list_empty(&queue->mainqueue)) {
-		uvc_trace(UVC_TRACE_CAPTURE, "[E] Empty buffer queue.\n");
-		ret = -EINVAL;
-		goto done;
-	}
-
-	buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream);
-	if ((ret = uvc_queue_waiton(buf, nonblocking)) < 0)
-		goto done;
-
-	uvc_trace(UVC_TRACE_CAPTURE, "Dequeuing buffer %u (%u, %u bytes).\n",
-		buf->buf.index, buf->state, buf->buf.bytesused);
-
-	switch (buf->state) {
-	case UVC_BUF_STATE_ERROR:
-		uvc_trace(UVC_TRACE_CAPTURE, "[W] Corrupted data "
-			"(transmission error).\n");
-		ret = -EIO;
-	case UVC_BUF_STATE_DONE:
-		buf->state = UVC_BUF_STATE_IDLE;
-		break;
-
-	case UVC_BUF_STATE_IDLE:
-	case UVC_BUF_STATE_QUEUED:
-	case UVC_BUF_STATE_ACTIVE:
-	case UVC_BUF_STATE_READY:
-	default:
-		uvc_trace(UVC_TRACE_CAPTURE, "[E] Invalid buffer state %u "
-			"(driver bug?).\n", buf->state);
-		ret = -EINVAL;
-		goto done;
-	}
-
-	list_del(&buf->stream);
-	__uvc_query_buffer(buf, v4l2_buf);
-
-done:
-	mutex_unlock(&queue->mutex);
-	return ret;
-}
-
-/*
- * VMA operations.
- */
-static void uvc_vm_open(struct vm_area_struct *vma)
-{
-	struct uvc_buffer *buffer = vma->vm_private_data;
-	buffer->vma_use_count++;
-}
-
-static void uvc_vm_close(struct vm_area_struct *vma)
-{
-	struct uvc_buffer *buffer = vma->vm_private_data;
-	buffer->vma_use_count--;
-}
-
-static const struct vm_operations_struct uvc_vm_ops = {
-	.open		= uvc_vm_open,
-	.close		= uvc_vm_close,
-};
-
-/*
- * Memory-map a video buffer.
- *
- * This function implements video buffers memory mapping and is intended to be
- * used by the device mmap handler.
- */
-int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
-{
-	struct uvc_buffer *uninitialized_var(buffer);
-	struct page *page;
-	unsigned long addr, start, size;
-	unsigned int i;
-	int ret = 0;
-
-	start = vma->vm_start;
-	size = vma->vm_end - vma->vm_start;
-
-	mutex_lock(&queue->mutex);
-
-	for (i = 0; i < queue->count; ++i) {
-		buffer = &queue->buffer[i];
-		if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
-			break;
-	}
-
-	if (i == queue->count || PAGE_ALIGN(size) != queue->buf_size) {
-		ret = -EINVAL;
-		goto done;
-	}
-
-	/*
-	 * VM_IO marks the area as being an mmaped region for I/O to a
-	 * device. It also prevents the region from being core dumped.
-	 */
-	vma->vm_flags |= VM_IO;
-
-	addr = (unsigned long)queue->mem + buffer->buf.m.offset;
-#ifdef CONFIG_MMU
-	while (size > 0) {
-		page = vmalloc_to_page((void *)addr);
-		if ((ret = vm_insert_page(vma, start, page)) < 0)
-			goto done;
-
-		start += PAGE_SIZE;
-		addr += PAGE_SIZE;
-		size -= PAGE_SIZE;
-	}
-#endif
-
-	vma->vm_ops = &uvc_vm_ops;
-	vma->vm_private_data = buffer;
-	uvc_vm_open(vma);
-
-done:
-	mutex_unlock(&queue->mutex);
-	return ret;
-}
-
-/*
- * Poll the video queue.
- *
- * This function implements video queue polling and is intended to be used by
- * the device poll handler.
- */
-unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file,
-		poll_table *wait)
-{
-	struct uvc_buffer *buf;
-	unsigned int mask = 0;
-
-	mutex_lock(&queue->mutex);
-	if (list_empty(&queue->mainqueue)) {
-		mask |= POLLERR;
-		goto done;
-	}
-	buf = list_first_entry(&queue->mainqueue, struct uvc_buffer, stream);
-
-	poll_wait(file, &buf->wait, wait);
-	if (buf->state == UVC_BUF_STATE_DONE ||
-	    buf->state == UVC_BUF_STATE_ERROR) {
-		if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
-			mask |= POLLIN | POLLRDNORM;
-		else
-			mask |= POLLOUT | POLLWRNORM;
-	}
-
-done:
-	mutex_unlock(&queue->mutex);
-	return mask;
-}
-
 #ifndef CONFIG_MMU
 /*
  * Get unmapped area.
@@ -515,7 +260,7 @@
 		ret = -EINVAL;
 		goto done;
 	}
-	ret = (unsigned long)queue->mem + buffer->buf.m.offset;
+	ret = (unsigned long)buf->mem;
 done:
 	mutex_unlock(&queue->mutex);
 	return ret;
@@ -540,27 +285,24 @@
  */
 int uvc_queue_enable(struct uvc_video_queue *queue, int enable)
 {
-	unsigned int i;
-	int ret = 0;
+	unsigned long flags;
+	int ret;
 
 	mutex_lock(&queue->mutex);
 	if (enable) {
-		if (uvc_queue_streaming(queue)) {
-			ret = -EBUSY;
+		ret = vb2_streamon(&queue->queue, queue->queue.type);
+		if (ret < 0)
 			goto done;
-		}
-		queue->flags |= UVC_QUEUE_STREAMING;
+
 		queue->buf_used = 0;
 	} else {
-		uvc_queue_cancel(queue, 0);
-		INIT_LIST_HEAD(&queue->mainqueue);
+		ret = vb2_streamoff(&queue->queue, queue->queue.type);
+		if (ret < 0)
+			goto done;
 
-		for (i = 0; i < queue->count; ++i) {
-			queue->buffer[i].error = 0;
-			queue->buffer[i].state = UVC_BUF_STATE_IDLE;
-		}
-
-		queue->flags &= ~UVC_QUEUE_STREAMING;
+		spin_lock_irqsave(&queue->irqlock, flags);
+		INIT_LIST_HEAD(&queue->irqqueue);
+		spin_unlock_irqrestore(&queue->irqlock, flags);
 	}
 
 done:
@@ -591,12 +333,12 @@
 				       queue);
 		list_del(&buf->queue);
 		buf->state = UVC_BUF_STATE_ERROR;
-		wake_up(&buf->wait);
+		vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR);
 	}
 	/* This must be protected by the irqlock spinlock to avoid race
-	 * conditions between uvc_queue_buffer and the disconnection event that
+	 * conditions between uvc_buffer_queue and the disconnection event that
 	 * could result in an interruptible wait in uvc_dequeue_buffer. Do not
-	 * blindly replace this logic by checking for the UVC_DEV_DISCONNECTED
+	 * blindly replace this logic by checking for the UVC_QUEUE_DISCONNECTED
 	 * state outside the queue code.
 	 */
 	if (disconnect)
@@ -613,14 +355,12 @@
 	if ((queue->flags & UVC_QUEUE_DROP_CORRUPTED) && buf->error) {
 		buf->error = 0;
 		buf->state = UVC_BUF_STATE_QUEUED;
-		buf->buf.bytesused = 0;
+		vb2_set_plane_payload(&buf->buf, 0, 0);
 		return buf;
 	}
 
 	spin_lock_irqsave(&queue->irqlock, flags);
 	list_del(&buf->queue);
-	buf->error = 0;
-	buf->state = UVC_BUF_STATE_DONE;
 	if (!list_empty(&queue->irqqueue))
 		nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
 					   queue);
@@ -628,7 +368,9 @@
 		nextbuf = NULL;
 	spin_unlock_irqrestore(&queue->irqlock, flags);
 
-	wake_up(&buf->wait);
+	buf->state = buf->error ? VB2_BUF_STATE_ERROR : UVC_BUF_STATE_DONE;
+	vb2_set_plane_payload(&buf->buf, 0, buf->bytesused);
+	vb2_buffer_done(&buf->buf, VB2_BUF_STATE_DONE);
+
 	return nextbuf;
 }
-
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index dadf11f..2ae4f88 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -58,6 +58,15 @@
 		break;
 
 	case V4L2_CTRL_TYPE_MENU:
+		/* Prevent excessive memory consumption, as well as integer
+		 * overflows.
+		 */
+		if (xmap->menu_count == 0 ||
+		    xmap->menu_count > UVC_MAX_CONTROL_MENU_ENTRIES) {
+			ret = -EINVAL;
+			goto done;
+		}
+
 		size = xmap->menu_count * sizeof(*map->menu_info);
 		map->menu_info = kmalloc(size, GFP_KERNEL);
 		if (map->menu_info == NULL) {
@@ -513,10 +522,7 @@
 	/* Only free resources if this is a privileged handle. */
 	if (uvc_has_privileges(handle)) {
 		uvc_video_enable(stream, 0);
-
-		if (uvc_free_buffers(&stream->queue) < 0)
-			uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to "
-					"free buffers.\n");
+		uvc_free_buffers(&stream->queue);
 	}
 
 	/* Release the file handle. */
@@ -914,19 +920,11 @@
 
 	/* Buffers & streaming */
 	case VIDIOC_REQBUFS:
-	{
-		struct v4l2_requestbuffers *rb = arg;
-
-		if (rb->type != stream->type ||
-		    rb->memory != V4L2_MEMORY_MMAP)
-			return -EINVAL;
-
 		if ((ret = uvc_acquire_privileges(handle)) < 0)
 			return ret;
 
 		mutex_lock(&stream->mutex);
-		ret = uvc_alloc_buffers(&stream->queue, rb->count,
-					stream->ctrl.dwMaxVideoFrameSize);
+		ret = uvc_alloc_buffers(&stream->queue, arg);
 		mutex_unlock(&stream->mutex);
 		if (ret < 0)
 			return ret;
@@ -934,18 +932,13 @@
 		if (ret == 0)
 			uvc_dismiss_privileges(handle);
 
-		rb->count = ret;
 		ret = 0;
 		break;
-	}
 
 	case VIDIOC_QUERYBUF:
 	{
 		struct v4l2_buffer *buf = arg;
 
-		if (buf->type != stream->type)
-			return -EINVAL;
-
 		if (!uvc_has_privileges(handle))
 			return -EBUSY;
 
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index b015e8e..c7e69b8 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -351,26 +351,554 @@
 	return ret;
 }
 
-int uvc_commit_video(struct uvc_streaming *stream,
-	struct uvc_streaming_control *probe)
+static int uvc_commit_video(struct uvc_streaming *stream,
+			    struct uvc_streaming_control *probe)
 {
 	return uvc_set_video_ctrl(stream, probe, 0);
 }
 
+/* -----------------------------------------------------------------------------
+ * Clocks and timestamps
+ */
+
+static void
+uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
+		       const __u8 *data, int len)
+{
+	struct uvc_clock_sample *sample;
+	unsigned int header_size;
+	bool has_pts = false;
+	bool has_scr = false;
+	unsigned long flags;
+	struct timespec ts;
+	u16 host_sof;
+	u16 dev_sof;
+
+	switch (data[1] & (UVC_STREAM_PTS | UVC_STREAM_SCR)) {
+	case UVC_STREAM_PTS | UVC_STREAM_SCR:
+		header_size = 12;
+		has_pts = true;
+		has_scr = true;
+		break;
+	case UVC_STREAM_PTS:
+		header_size = 6;
+		has_pts = true;
+		break;
+	case UVC_STREAM_SCR:
+		header_size = 8;
+		has_scr = true;
+		break;
+	default:
+		header_size = 2;
+		break;
+	}
+
+	/* Check for invalid headers. */
+	if (len < header_size)
+		return;
+
+	/* Extract the timestamps:
+	 *
+	 * - store the frame PTS in the buffer structure
+	 * - if the SCR field is present, retrieve the host SOF counter and
+	 *   kernel timestamps and store them with the SCR STC and SOF fields
+	 *   in the ring buffer
+	 */
+	if (has_pts && buf != NULL)
+		buf->pts = get_unaligned_le32(&data[2]);
+
+	if (!has_scr)
+		return;
+
+	/* To limit the amount of data, drop SCRs with an SOF identical to the
+	 * previous one.
+	 */
+	dev_sof = get_unaligned_le16(&data[header_size - 2]);
+	if (dev_sof == stream->clock.last_sof)
+		return;
+
+	stream->clock.last_sof = dev_sof;
+
+	host_sof = usb_get_current_frame_number(stream->dev->udev);
+	ktime_get_ts(&ts);
+
+	/* The UVC specification allows device implementations that can't obtain
+	 * the USB frame number to keep their own frame counters as long as they
+	 * match the size and frequency of the frame number associated with USB
+	 * SOF tokens. The SOF values sent by such devices differ from the USB
+	 * SOF tokens by a fixed offset that needs to be estimated and accounted
+	 * for to make timestamp recovery as accurate as possible.
+	 *
+	 * The offset is estimated the first time a device SOF value is received
+	 * as the difference between the host and device SOF values. As the two
+	 * SOF values can differ slightly due to transmission delays, consider
+	 * that the offset is null if the difference is not higher than 10 ms
+	 * (negative differences can not happen and are thus considered as an
+	 * offset). The video commit control wDelay field should be used to
+	 * compute a dynamic threshold instead of using a fixed 10 ms value, but
+	 * devices don't report reliable wDelay values.
+	 *
+	 * See uvc_video_clock_host_sof() for an explanation regarding why only
+	 * the 8 LSBs of the delta are kept.
+	 */
+	if (stream->clock.sof_offset == (u16)-1) {
+		u16 delta_sof = (host_sof - dev_sof) & 255;
+		if (delta_sof >= 10)
+			stream->clock.sof_offset = delta_sof;
+		else
+			stream->clock.sof_offset = 0;
+	}
+
+	dev_sof = (dev_sof + stream->clock.sof_offset) & 2047;
+
+	spin_lock_irqsave(&stream->clock.lock, flags);
+
+	sample = &stream->clock.samples[stream->clock.head];
+	sample->dev_stc = get_unaligned_le32(&data[header_size - 6]);
+	sample->dev_sof = dev_sof;
+	sample->host_sof = host_sof;
+	sample->host_ts = ts;
+
+	/* Update the sliding window head and count. */
+	stream->clock.head = (stream->clock.head + 1) % stream->clock.size;
+
+	if (stream->clock.count < stream->clock.size)
+		stream->clock.count++;
+
+	spin_unlock_irqrestore(&stream->clock.lock, flags);
+}
+
+static int uvc_video_clock_init(struct uvc_streaming *stream)
+{
+	struct uvc_clock *clock = &stream->clock;
+
+	spin_lock_init(&clock->lock);
+	clock->head = 0;
+	clock->count = 0;
+	clock->size = 32;
+	clock->last_sof = -1;
+	clock->sof_offset = -1;
+
+	clock->samples = kmalloc(clock->size * sizeof(*clock->samples),
+				 GFP_KERNEL);
+	if (clock->samples == NULL)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void uvc_video_clock_cleanup(struct uvc_streaming *stream)
+{
+	kfree(stream->clock.samples);
+	stream->clock.samples = NULL;
+}
+
+/*
+ * uvc_video_clock_host_sof - Return the host SOF value for a clock sample
+ *
+ * Host SOF counters reported by usb_get_current_frame_number() usually don't
+ * cover the whole 11-bits SOF range (0-2047) but are limited to the HCI frame
+ * schedule window. They can be limited to 8, 9 or 10 bits depending on the host
+ * controller and its configuration.
+ *
+ * We thus need to recover the SOF value corresponding to the host frame number.
+ * As the device and host frame numbers are sampled in a short interval, the
+ * difference between their values should be equal to a small delta plus an
+ * integer multiple of 256 caused by the host frame number limited precision.
+ *
+ * To obtain the recovered host SOF value, compute the small delta by masking
+ * the high bits of the host frame counter and device SOF difference and add it
+ * to the device SOF value.
+ */
+static u16 uvc_video_clock_host_sof(const struct uvc_clock_sample *sample)
+{
+	/* The delta value can be negative. */
+	s8 delta_sof;
+
+	delta_sof = (sample->host_sof - sample->dev_sof) & 255;
+
+	return (sample->dev_sof + delta_sof) & 2047;
+}
+
+/*
+ * uvc_video_clock_update - Update the buffer timestamp
+ *
+ * This function converts the buffer PTS timestamp to the host clock domain by
+ * going through the USB SOF clock domain and stores the result in the V4L2
+ * buffer timestamp field.
+ *
+ * The relationship between the device clock and the host clock isn't known.
+ * However, the device and the host share the common USB SOF clock which can be
+ * used to recover that relationship.
+ *
+ * The relationship between the device clock and the USB SOF clock is considered
+ * to be linear over the clock samples sliding window and is given by
+ *
+ * SOF = m * PTS + p
+ *
+ * Several methods to compute the slope (m) and intercept (p) can be used. As
+ * the clock drift should be small compared to the sliding window size, we
+ * assume that the line that goes through the points at both ends of the window
+ * is a good approximation. Naming those points P1 and P2, we get
+ *
+ * SOF = (SOF2 - SOF1) / (STC2 - STC1) * PTS
+ *     + (SOF1 * STC2 - SOF2 * STC1) / (STC2 - STC1)
+ *
+ * or
+ *
+ * SOF = ((SOF2 - SOF1) * PTS + SOF1 * STC2 - SOF2 * STC1) / (STC2 - STC1)   (1)
+ *
+ * to avoid loosing precision in the division. Similarly, the host timestamp is
+ * computed with
+ *
+ * TS = ((TS2 - TS1) * PTS + TS1 * SOF2 - TS2 * SOF1) / (SOF2 - SOF1)	     (2)
+ *
+ * SOF values are coded on 11 bits by USB. We extend their precision with 16
+ * decimal bits, leading to a 11.16 coding.
+ *
+ * TODO: To avoid surprises with device clock values, PTS/STC timestamps should
+ * be normalized using the nominal device clock frequency reported through the
+ * UVC descriptors.
+ *
+ * Both the PTS/STC and SOF counters roll over, after a fixed but device
+ * specific amount of time for PTS/STC and after 2048ms for SOF. As long as the
+ * sliding window size is smaller than the rollover period, differences computed
+ * on unsigned integers will produce the correct result. However, the p term in
+ * the linear relations will be miscomputed.
+ *
+ * To fix the issue, we subtract a constant from the PTS and STC values to bring
+ * PTS to half the 32 bit STC range. The sliding window STC values then fit into
+ * the 32 bit range without any rollover.
+ *
+ * Similarly, we add 2048 to the device SOF values to make sure that the SOF
+ * computed by (1) will never be smaller than 0. This offset is then compensated
+ * by adding 2048 to the SOF values used in (2). However, this doesn't prevent
+ * rollovers between (1) and (2): the SOF value computed by (1) can be slightly
+ * lower than 4096, and the host SOF counters can have rolled over to 2048. This
+ * case is handled by subtracting 2048 from the SOF value if it exceeds the host
+ * SOF value at the end of the sliding window.
+ *
+ * Finally we subtract a constant from the host timestamps to bring the first
+ * timestamp of the sliding window to 1s.
+ */
+void uvc_video_clock_update(struct uvc_streaming *stream,
+			    struct v4l2_buffer *v4l2_buf,
+			    struct uvc_buffer *buf)
+{
+	struct uvc_clock *clock = &stream->clock;
+	struct uvc_clock_sample *first;
+	struct uvc_clock_sample *last;
+	unsigned long flags;
+	struct timespec ts;
+	u32 delta_stc;
+	u32 y1, y2;
+	u32 x1, x2;
+	u32 mean;
+	u32 sof;
+	u32 div;
+	u32 rem;
+	u64 y;
+
+	spin_lock_irqsave(&clock->lock, flags);
+
+	if (clock->count < clock->size)
+		goto done;
+
+	first = &clock->samples[clock->head];
+	last = &clock->samples[(clock->head - 1) % clock->size];
+
+	/* First step, PTS to SOF conversion. */
+	delta_stc = buf->pts - (1UL << 31);
+	x1 = first->dev_stc - delta_stc;
+	x2 = last->dev_stc - delta_stc;
+	y1 = (first->dev_sof + 2048) << 16;
+	y2 = (last->dev_sof + 2048) << 16;
+
+	if (y2 < y1)
+		y2 += 2048 << 16;
+
+	y = (u64)(y2 - y1) * (1ULL << 31) + (u64)y1 * (u64)x2
+	  - (u64)y2 * (u64)x1;
+	y = div_u64(y, x2 - x1);
+
+	sof = y;
+
+	uvc_trace(UVC_TRACE_CLOCK, "%s: PTS %u y %llu.%06llu SOF %u.%06llu "
+		  "(x1 %u x2 %u y1 %u y2 %u SOF offset %u)\n",
+		  stream->dev->name, buf->pts,
+		  y >> 16, div_u64((y & 0xffff) * 1000000, 65536),
+		  sof >> 16, div_u64(((u64)sof & 0xffff) * 1000000LLU, 65536),
+		  x1, x2, y1, y2, clock->sof_offset);
+
+	/* Second step, SOF to host clock conversion. */
+	ts = timespec_sub(last->host_ts, first->host_ts);
+	x1 = (uvc_video_clock_host_sof(first) + 2048) << 16;
+	x2 = (uvc_video_clock_host_sof(last) + 2048) << 16;
+	y1 = NSEC_PER_SEC;
+	y2 = (ts.tv_sec + 1) * NSEC_PER_SEC + ts.tv_nsec;
+
+	if (x2 < x1)
+		x2 += 2048 << 16;
+
+	/* Interpolated and host SOF timestamps can wrap around at slightly
+	 * different times. Handle this by adding or removing 2048 to or from
+	 * the computed SOF value to keep it close to the SOF samples mean
+	 * value.
+	 */
+	mean = (x1 + x2) / 2;
+	if (mean - (1024 << 16) > sof)
+		sof += 2048 << 16;
+	else if (sof > mean + (1024 << 16))
+		sof -= 2048 << 16;
+
+	y = (u64)(y2 - y1) * (u64)sof + (u64)y1 * (u64)x2
+	  - (u64)y2 * (u64)x1;
+	y = div_u64(y, x2 - x1);
+
+	div = div_u64_rem(y, NSEC_PER_SEC, &rem);
+	ts.tv_sec = first->host_ts.tv_sec - 1 + div;
+	ts.tv_nsec = first->host_ts.tv_nsec + rem;
+	if (ts.tv_nsec >= NSEC_PER_SEC) {
+		ts.tv_sec++;
+		ts.tv_nsec -= NSEC_PER_SEC;
+	}
+
+	uvc_trace(UVC_TRACE_CLOCK, "%s: SOF %u.%06llu y %llu ts %lu.%06lu "
+		  "buf ts %lu.%06lu (x1 %u/%u/%u x2 %u/%u/%u y1 %u y2 %u)\n",
+		  stream->dev->name,
+		  sof >> 16, div_u64(((u64)sof & 0xffff) * 1000000LLU, 65536),
+		  y, ts.tv_sec, ts.tv_nsec / NSEC_PER_USEC,
+		  v4l2_buf->timestamp.tv_sec, v4l2_buf->timestamp.tv_usec,
+		  x1, first->host_sof, first->dev_sof,
+		  x2, last->host_sof, last->dev_sof, y1, y2);
+
+	/* Update the V4L2 buffer. */
+	v4l2_buf->timestamp.tv_sec = ts.tv_sec;
+	v4l2_buf->timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
+
+done:
+	spin_unlock_irqrestore(&stream->clock.lock, flags);
+}
+
+/* ------------------------------------------------------------------------
+ * Stream statistics
+ */
+
+static void uvc_video_stats_decode(struct uvc_streaming *stream,
+		const __u8 *data, int len)
+{
+	unsigned int header_size;
+	bool has_pts = false;
+	bool has_scr = false;
+	u16 uninitialized_var(scr_sof);
+	u32 uninitialized_var(scr_stc);
+	u32 uninitialized_var(pts);
+
+	if (stream->stats.stream.nb_frames == 0 &&
+	    stream->stats.frame.nb_packets == 0)
+		ktime_get_ts(&stream->stats.stream.start_ts);
+
+	switch (data[1] & (UVC_STREAM_PTS | UVC_STREAM_SCR)) {
+	case UVC_STREAM_PTS | UVC_STREAM_SCR:
+		header_size = 12;
+		has_pts = true;
+		has_scr = true;
+		break;
+	case UVC_STREAM_PTS:
+		header_size = 6;
+		has_pts = true;
+		break;
+	case UVC_STREAM_SCR:
+		header_size = 8;
+		has_scr = true;
+		break;
+	default:
+		header_size = 2;
+		break;
+	}
+
+	/* Check for invalid headers. */
+	if (len < header_size || data[0] < header_size) {
+		stream->stats.frame.nb_invalid++;
+		return;
+	}
+
+	/* Extract the timestamps. */
+	if (has_pts)
+		pts = get_unaligned_le32(&data[2]);
+
+	if (has_scr) {
+		scr_stc = get_unaligned_le32(&data[header_size - 6]);
+		scr_sof = get_unaligned_le16(&data[header_size - 2]);
+	}
+
+	/* Is PTS constant through the whole frame ? */
+	if (has_pts && stream->stats.frame.nb_pts) {
+		if (stream->stats.frame.pts != pts) {
+			stream->stats.frame.nb_pts_diffs++;
+			stream->stats.frame.last_pts_diff =
+				stream->stats.frame.nb_packets;
+		}
+	}
+
+	if (has_pts) {
+		stream->stats.frame.nb_pts++;
+		stream->stats.frame.pts = pts;
+	}
+
+	/* Do all frames have a PTS in their first non-empty packet, or before
+	 * their first empty packet ?
+	 */
+	if (stream->stats.frame.size == 0) {
+		if (len > header_size)
+			stream->stats.frame.has_initial_pts = has_pts;
+		if (len == header_size && has_pts)
+			stream->stats.frame.has_early_pts = true;
+	}
+
+	/* Do the SCR.STC and SCR.SOF fields vary through the frame ? */
+	if (has_scr && stream->stats.frame.nb_scr) {
+		if (stream->stats.frame.scr_stc != scr_stc)
+			stream->stats.frame.nb_scr_diffs++;
+	}
+
+	if (has_scr) {
+		/* Expand the SOF counter to 32 bits and store its value. */
+		if (stream->stats.stream.nb_frames > 0 ||
+		    stream->stats.frame.nb_scr > 0)
+			stream->stats.stream.scr_sof_count +=
+				(scr_sof - stream->stats.stream.scr_sof) % 2048;
+		stream->stats.stream.scr_sof = scr_sof;
+
+		stream->stats.frame.nb_scr++;
+		stream->stats.frame.scr_stc = scr_stc;
+		stream->stats.frame.scr_sof = scr_sof;
+
+		if (scr_sof < stream->stats.stream.min_sof)
+			stream->stats.stream.min_sof = scr_sof;
+		if (scr_sof > stream->stats.stream.max_sof)
+			stream->stats.stream.max_sof = scr_sof;
+	}
+
+	/* Record the first non-empty packet number. */
+	if (stream->stats.frame.size == 0 && len > header_size)
+		stream->stats.frame.first_data = stream->stats.frame.nb_packets;
+
+	/* Update the frame size. */
+	stream->stats.frame.size += len - header_size;
+
+	/* Update the packets counters. */
+	stream->stats.frame.nb_packets++;
+	if (len > header_size)
+		stream->stats.frame.nb_empty++;
+
+	if (data[1] & UVC_STREAM_ERR)
+		stream->stats.frame.nb_errors++;
+}
+
+static void uvc_video_stats_update(struct uvc_streaming *stream)
+{
+	struct uvc_stats_frame *frame = &stream->stats.frame;
+
+	uvc_trace(UVC_TRACE_STATS, "frame %u stats: %u/%u/%u packets, "
+		  "%u/%u/%u pts (%searly %sinitial), %u/%u scr, "
+		  "last pts/stc/sof %u/%u/%u\n",
+		  stream->sequence, frame->first_data,
+		  frame->nb_packets - frame->nb_empty, frame->nb_packets,
+		  frame->nb_pts_diffs, frame->last_pts_diff, frame->nb_pts,
+		  frame->has_early_pts ? "" : "!",
+		  frame->has_initial_pts ? "" : "!",
+		  frame->nb_scr_diffs, frame->nb_scr,
+		  frame->pts, frame->scr_stc, frame->scr_sof);
+
+	stream->stats.stream.nb_frames++;
+	stream->stats.stream.nb_packets += stream->stats.frame.nb_packets;
+	stream->stats.stream.nb_empty += stream->stats.frame.nb_empty;
+	stream->stats.stream.nb_errors += stream->stats.frame.nb_errors;
+	stream->stats.stream.nb_invalid += stream->stats.frame.nb_invalid;
+
+	if (frame->has_early_pts)
+		stream->stats.stream.nb_pts_early++;
+	if (frame->has_initial_pts)
+		stream->stats.stream.nb_pts_initial++;
+	if (frame->last_pts_diff <= frame->first_data)
+		stream->stats.stream.nb_pts_constant++;
+	if (frame->nb_scr >= frame->nb_packets - frame->nb_empty)
+		stream->stats.stream.nb_scr_count_ok++;
+	if (frame->nb_scr_diffs + 1 == frame->nb_scr)
+		stream->stats.stream.nb_scr_diffs_ok++;
+
+	memset(&stream->stats.frame, 0, sizeof(stream->stats.frame));
+}
+
+size_t uvc_video_stats_dump(struct uvc_streaming *stream, char *buf,
+			    size_t size)
+{
+	unsigned int scr_sof_freq;
+	unsigned int duration;
+	struct timespec ts;
+	size_t count = 0;
+
+	ts.tv_sec = stream->stats.stream.stop_ts.tv_sec
+		  - stream->stats.stream.start_ts.tv_sec;
+	ts.tv_nsec = stream->stats.stream.stop_ts.tv_nsec
+		   - stream->stats.stream.start_ts.tv_nsec;
+	if (ts.tv_nsec < 0) {
+		ts.tv_sec--;
+		ts.tv_nsec += 1000000000;
+	}
+
+	/* Compute the SCR.SOF frequency estimate. At the nominal 1kHz SOF
+	 * frequency this will not overflow before more than 1h.
+	 */
+	duration = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
+	if (duration != 0)
+		scr_sof_freq = stream->stats.stream.scr_sof_count * 1000
+			     / duration;
+	else
+		scr_sof_freq = 0;
+
+	count += scnprintf(buf + count, size - count,
+			   "frames:  %u\npackets: %u\nempty:   %u\n"
+			   "errors:  %u\ninvalid: %u\n",
+			   stream->stats.stream.nb_frames,
+			   stream->stats.stream.nb_packets,
+			   stream->stats.stream.nb_empty,
+			   stream->stats.stream.nb_errors,
+			   stream->stats.stream.nb_invalid);
+	count += scnprintf(buf + count, size - count,
+			   "pts: %u early, %u initial, %u ok\n",
+			   stream->stats.stream.nb_pts_early,
+			   stream->stats.stream.nb_pts_initial,
+			   stream->stats.stream.nb_pts_constant);
+	count += scnprintf(buf + count, size - count,
+			   "scr: %u count ok, %u diff ok\n",
+			   stream->stats.stream.nb_scr_count_ok,
+			   stream->stats.stream.nb_scr_diffs_ok);
+	count += scnprintf(buf + count, size - count,
+			   "sof: %u <= sof <= %u, freq %u.%03u kHz\n",
+			   stream->stats.stream.min_sof,
+			   stream->stats.stream.max_sof,
+			   scr_sof_freq / 1000, scr_sof_freq % 1000);
+
+	return count;
+}
+
+static void uvc_video_stats_start(struct uvc_streaming *stream)
+{
+	memset(&stream->stats, 0, sizeof(stream->stats));
+	stream->stats.stream.min_sof = 2048;
+}
+
+static void uvc_video_stats_stop(struct uvc_streaming *stream)
+{
+	ktime_get_ts(&stream->stats.stream.stop_ts);
+}
+
 /* ------------------------------------------------------------------------
  * Video codecs
  */
 
-/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
-#define UVC_STREAM_EOH	(1 << 7)
-#define UVC_STREAM_ERR	(1 << 6)
-#define UVC_STREAM_STI	(1 << 5)
-#define UVC_STREAM_RES	(1 << 4)
-#define UVC_STREAM_SCR	(1 << 3)
-#define UVC_STREAM_PTS	(1 << 2)
-#define UVC_STREAM_EOF	(1 << 1)
-#define UVC_STREAM_FID	(1 << 0)
-
 /* Video payload decoding is handled by uvc_video_decode_start(),
  * uvc_video_decode_data() and uvc_video_decode_end().
  *
@@ -416,14 +944,9 @@
 	 * - bHeaderLength value must be at least 2 bytes (see above)
 	 * - bHeaderLength value can't be larger than the packet size.
 	 */
-	if (len < 2 || data[0] < 2 || data[0] > len)
+	if (len < 2 || data[0] < 2 || data[0] > len) {
+		stream->stats.frame.nb_invalid++;
 		return -EINVAL;
-
-	/* Skip payloads marked with the error bit ("error frames"). */
-	if (data[1] & UVC_STREAM_ERR) {
-		uvc_trace(UVC_TRACE_FRAME, "Dropping payload (error bit "
-			  "set).\n");
-		return -ENODATA;
 	}
 
 	fid = data[1] & UVC_STREAM_FID;
@@ -431,8 +954,14 @@
 	/* Increase the sequence number regardless of any buffer states, so
 	 * that discontinuous sequence numbers always indicate lost frames.
 	 */
-	if (stream->last_fid != fid)
+	if (stream->last_fid != fid) {
 		stream->sequence++;
+		if (stream->sequence)
+			uvc_video_stats_update(stream);
+	}
+
+	uvc_video_clock_decode(stream, buf, data, len);
+	uvc_video_stats_decode(stream, data, len);
 
 	/* Store the payload FID bit and return immediately when the buffer is
 	 * NULL.
@@ -442,6 +971,13 @@
 		return -ENODATA;
 	}
 
+	/* Mark the buffer as bad if the error bit is set. */
+	if (data[1] & UVC_STREAM_ERR) {
+		uvc_trace(UVC_TRACE_FRAME, "Marking buffer as bad (error bit "
+			  "set).\n");
+		buf->error = 1;
+	}
+
 	/* Synchronize to the input stream by waiting for the FID bit to be
 	 * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE.
 	 * stream->last_fid is initialized to -1, so the first isochronous
@@ -467,9 +1003,10 @@
 		else
 			ktime_get_real_ts(&ts);
 
-		buf->buf.sequence = stream->sequence;
-		buf->buf.timestamp.tv_sec = ts.tv_sec;
-		buf->buf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
+		buf->buf.v4l2_buf.sequence = stream->sequence;
+		buf->buf.v4l2_buf.timestamp.tv_sec = ts.tv_sec;
+		buf->buf.v4l2_buf.timestamp.tv_usec =
+			ts.tv_nsec / NSEC_PER_USEC;
 
 		/* TODO: Handle PTS and SCR. */
 		buf->state = UVC_BUF_STATE_ACTIVE;
@@ -490,7 +1027,7 @@
 	 * avoids detecting end of frame conditions at FID toggling if the
 	 * previous payload had the EOF bit set.
 	 */
-	if (fid != stream->last_fid && buf->buf.bytesused != 0) {
+	if (fid != stream->last_fid && buf->bytesused != 0) {
 		uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit "
 				"toggled).\n");
 		buf->state = UVC_BUF_STATE_READY;
@@ -505,7 +1042,6 @@
 static void uvc_video_decode_data(struct uvc_streaming *stream,
 		struct uvc_buffer *buf, const __u8 *data, int len)
 {
-	struct uvc_video_queue *queue = &stream->queue;
 	unsigned int maxlen, nbytes;
 	void *mem;
 
@@ -513,11 +1049,11 @@
 		return;
 
 	/* Copy the video data to the buffer. */
-	maxlen = buf->buf.length - buf->buf.bytesused;
-	mem = queue->mem + buf->buf.m.offset + buf->buf.bytesused;
+	maxlen = buf->length - buf->bytesused;
+	mem = buf->mem + buf->bytesused;
 	nbytes = min((unsigned int)len, maxlen);
 	memcpy(mem, data, nbytes);
-	buf->buf.bytesused += nbytes;
+	buf->bytesused += nbytes;
 
 	/* Complete the current frame if the buffer size was exceeded. */
 	if (len > maxlen) {
@@ -530,7 +1066,7 @@
 		struct uvc_buffer *buf, const __u8 *data, int len)
 {
 	/* Mark the buffer as done if the EOF marker is set. */
-	if (data[1] & UVC_STREAM_EOF && buf->buf.bytesused != 0) {
+	if (data[1] & UVC_STREAM_EOF && buf->bytesused != 0) {
 		uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n");
 		if (data[0] == len)
 			uvc_trace(UVC_TRACE_FRAME, "EOF in empty payload.\n");
@@ -568,8 +1104,8 @@
 	void *mem;
 
 	/* Copy video data to the URB buffer. */
-	mem = queue->mem + buf->buf.m.offset + queue->buf_used;
-	nbytes = min((unsigned int)len, buf->buf.bytesused - queue->buf_used);
+	mem = buf->mem + queue->buf_used;
+	nbytes = min((unsigned int)len, buf->bytesused - queue->buf_used);
 	nbytes = min(stream->bulk.max_payload_size - stream->bulk.payload_size,
 			nbytes);
 	memcpy(data, mem, nbytes);
@@ -624,7 +1160,7 @@
 			urb->iso_frame_desc[i].actual_length);
 
 		if (buf->state == UVC_BUF_STATE_READY) {
-			if (buf->buf.length != buf->buf.bytesused &&
+			if (buf->length != buf->bytesused &&
 			    !(stream->cur_format->flags &
 			      UVC_FMT_FLAG_COMPRESSED))
 				buf->error = 1;
@@ -724,12 +1260,12 @@
 	stream->bulk.payload_size += ret;
 	len -= ret;
 
-	if (buf->buf.bytesused == stream->queue.buf_used ||
+	if (buf->bytesused == stream->queue.buf_used ||
 	    stream->bulk.payload_size == stream->bulk.max_payload_size) {
-		if (buf->buf.bytesused == stream->queue.buf_used) {
+		if (buf->bytesused == stream->queue.buf_used) {
 			stream->queue.buf_used = 0;
 			buf->state = UVC_BUF_STATE_READY;
-			buf->buf.sequence = ++stream->sequence;
+			buf->buf.v4l2_buf.sequence = ++stream->sequence;
 			uvc_queue_next_buffer(&stream->queue, buf);
 			stream->last_fid ^= UVC_STREAM_FID;
 		}
@@ -870,6 +1406,8 @@
 	struct urb *urb;
 	unsigned int i;
 
+	uvc_video_stats_stop(stream);
+
 	for (i = 0; i < UVC_URBS; ++i) {
 		urb = stream->urb[i];
 		if (urb == NULL)
@@ -882,6 +1420,8 @@
 
 	if (free_buffers)
 		uvc_free_urb_buffers(stream);
+
+	uvc_video_clock_cleanup(stream);
 }
 
 /*
@@ -1009,6 +1549,12 @@
 	stream->bulk.skip_payload = 0;
 	stream->bulk.payload_size = 0;
 
+	uvc_video_stats_start(stream);
+
+	ret = uvc_video_clock_init(stream);
+	if (ret < 0)
+		return ret;
+
 	if (intf->num_altsetting > 1) {
 		struct usb_host_endpoint *best_ep = NULL;
 		unsigned int best_psize = 3 * 1024;
@@ -1283,6 +1829,11 @@
 		return ret;
 	}
 
-	return uvc_init_video(stream, GFP_KERNEL);
-}
+	ret = uvc_init_video(stream, GFP_KERNEL);
+	if (ret < 0) {
+		usb_set_interface(stream->dev->udev, stream->intfnum, 0);
+		uvc_queue_enable(&stream->queue, 0);
+	}
 
+	return ret;
+}
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 4c1392e..67f88d8 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -13,6 +13,7 @@
 #include <linux/videodev2.h>
 #include <media/media-device.h>
 #include <media/v4l2-device.h>
+#include <media/videobuf2-core.h>
 
 /* --------------------------------------------------------------------------
  * UVC constants
@@ -113,6 +114,7 @@
 
 /* Maximum allowed number of control mappings per device */
 #define UVC_MAX_CONTROL_MAPPINGS	1024
+#define UVC_MAX_CONTROL_MENU_ENTRIES	32
 
 /* Devices quirks */
 #define UVC_QUIRK_STATUS_INTERVAL	0x00000001
@@ -319,35 +321,30 @@
 };
 
 struct uvc_buffer {
-	unsigned long vma_use_count;
-	struct list_head stream;
-
-	/* Touched by interrupt handler. */
-	struct v4l2_buffer buf;
+	struct vb2_buffer buf;
 	struct list_head queue;
-	wait_queue_head_t wait;
+
 	enum uvc_buffer_state state;
 	unsigned int error;
-};
-
-#define UVC_QUEUE_STREAMING		(1 << 0)
-#define UVC_QUEUE_DISCONNECTED		(1 << 1)
-#define UVC_QUEUE_DROP_CORRUPTED	(1 << 2)
-
-struct uvc_video_queue {
-	enum v4l2_buf_type type;
 
 	void *mem;
+	unsigned int length;
+	unsigned int bytesused;
+
+	u32 pts;
+};
+
+#define UVC_QUEUE_DISCONNECTED		(1 << 0)
+#define UVC_QUEUE_DROP_CORRUPTED	(1 << 1)
+
+struct uvc_video_queue {
+	struct vb2_queue queue;
+	struct mutex mutex;			/* Protects queue */
+
 	unsigned int flags;
-
-	unsigned int count;
-	unsigned int buf_size;
 	unsigned int buf_used;
-	struct uvc_buffer buffer[UVC_MAX_VIDEO_BUFFERS];
-	struct mutex mutex;	/* protects buffers and mainqueue */
-	spinlock_t irqlock;	/* protects irqqueue */
 
-	struct list_head mainqueue;
+	spinlock_t irqlock;			/* Protects irqqueue */
 	struct list_head irqqueue;
 };
 
@@ -362,6 +359,51 @@
 	struct mutex ctrl_mutex;		/* Protects ctrl.info */
 };
 
+struct uvc_stats_frame {
+	unsigned int size;		/* Number of bytes captured */
+	unsigned int first_data;	/* Index of the first non-empty packet */
+
+	unsigned int nb_packets;	/* Number of packets */
+	unsigned int nb_empty;		/* Number of empty packets */
+	unsigned int nb_invalid;	/* Number of packets with an invalid header */
+	unsigned int nb_errors;		/* Number of packets with the error bit set */
+
+	unsigned int nb_pts;		/* Number of packets with a PTS timestamp */
+	unsigned int nb_pts_diffs;	/* Number of PTS differences inside a frame */
+	unsigned int last_pts_diff;	/* Index of the last PTS difference */
+	bool has_initial_pts;		/* Whether the first non-empty packet has a PTS */
+	bool has_early_pts;		/* Whether a PTS is present before the first non-empty packet */
+	u32 pts;			/* PTS of the last packet */
+
+	unsigned int nb_scr;		/* Number of packets with a SCR timestamp */
+	unsigned int nb_scr_diffs;	/* Number of SCR.STC differences inside a frame */
+	u16 scr_sof;			/* SCR.SOF of the last packet */
+	u32 scr_stc;			/* SCR.STC of the last packet */
+};
+
+struct uvc_stats_stream {
+	struct timespec start_ts;	/* Stream start timestamp */
+	struct timespec stop_ts;	/* Stream stop timestamp */
+
+	unsigned int nb_frames;		/* Number of frames */
+
+	unsigned int nb_packets;	/* Number of packets */
+	unsigned int nb_empty;		/* Number of empty packets */
+	unsigned int nb_invalid;	/* Number of packets with an invalid header */
+	unsigned int nb_errors;		/* Number of packets with the error bit set */
+
+	unsigned int nb_pts_constant;	/* Number of frames with constant PTS */
+	unsigned int nb_pts_early;	/* Number of frames with early PTS */
+	unsigned int nb_pts_initial;	/* Number of frames with initial PTS */
+
+	unsigned int nb_scr_count_ok;	/* Number of frames with at least one SCR per non empty packet */
+	unsigned int nb_scr_diffs_ok;	/* Number of frames with varying SCR.STC */
+	unsigned int scr_sof_count;	/* STC.SOF counter accumulated since stream start */
+	unsigned int scr_sof;		/* STC.SOF of the last packet */
+	unsigned int min_sof;		/* Minimum STC.SOF value */
+	unsigned int max_sof;		/* Maximum STC.SOF value */
+};
+
 struct uvc_streaming {
 	struct list_head list;
 	struct uvc_device *dev;
@@ -387,6 +429,7 @@
 	 */
 	struct mutex mutex;
 
+	/* Buffers queue. */
 	unsigned int frozen : 1;
 	struct uvc_video_queue queue;
 	void (*decode) (struct urb *urb, struct uvc_streaming *video,
@@ -408,6 +451,32 @@
 
 	__u32 sequence;
 	__u8 last_fid;
+
+	/* debugfs */
+	struct dentry *debugfs_dir;
+	struct {
+		struct uvc_stats_frame frame;
+		struct uvc_stats_stream stream;
+	} stats;
+
+	/* Timestamps support. */
+	struct uvc_clock {
+		struct uvc_clock_sample {
+			u32 dev_stc;
+			u16 dev_sof;
+			struct timespec host_ts;
+			u16 host_sof;
+		} *samples;
+
+		unsigned int head;
+		unsigned int count;
+		unsigned int size;
+
+		u16 last_sof;
+		u16 sof_offset;
+
+		spinlock_t lock;
+	} clock;
 };
 
 enum uvc_device_state {
@@ -479,9 +548,12 @@
 #define UVC_TRACE_SUSPEND	(1 << 8)
 #define UVC_TRACE_STATUS	(1 << 9)
 #define UVC_TRACE_VIDEO		(1 << 10)
+#define UVC_TRACE_STATS		(1 << 11)
+#define UVC_TRACE_CLOCK		(1 << 12)
 
 #define UVC_WARN_MINMAX		0
 #define UVC_WARN_PROBE_DEF	1
+#define UVC_WARN_XU_GET_RES	2
 
 extern unsigned int uvc_clock_param;
 extern unsigned int uvc_no_drop_param;
@@ -516,8 +588,8 @@
 extern void uvc_queue_init(struct uvc_video_queue *queue,
 		enum v4l2_buf_type type, int drop_corrupted);
 extern int uvc_alloc_buffers(struct uvc_video_queue *queue,
-		unsigned int nbuffers, unsigned int buflength);
-extern int uvc_free_buffers(struct uvc_video_queue *queue);
+		struct v4l2_requestbuffers *rb);
+extern void uvc_free_buffers(struct uvc_video_queue *queue);
 extern int uvc_query_buffer(struct uvc_video_queue *queue,
 		struct v4l2_buffer *v4l2_buf);
 extern int uvc_queue_buffer(struct uvc_video_queue *queue,
@@ -539,7 +611,7 @@
 extern int uvc_queue_allocated(struct uvc_video_queue *queue);
 static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
 {
-	return queue->flags & UVC_QUEUE_STREAMING;
+	return vb2_is_streaming(&queue->queue);
 }
 
 /* V4L2 interface */
@@ -556,10 +628,11 @@
 extern int uvc_video_enable(struct uvc_streaming *stream, int enable);
 extern int uvc_probe_video(struct uvc_streaming *stream,
 		struct uvc_streaming_control *probe);
-extern int uvc_commit_video(struct uvc_streaming *stream,
-		struct uvc_streaming_control *ctrl);
 extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
 		__u8 intfnum, __u8 cs, void *data, __u16 size);
+void uvc_video_clock_update(struct uvc_streaming *stream,
+			    struct v4l2_buffer *v4l2_buf,
+			    struct uvc_buffer *buf);
 
 /* Status */
 extern int uvc_status_init(struct uvc_device *dev);
@@ -612,4 +685,13 @@
 void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream,
 		struct uvc_buffer *buf);
 
+/* debugfs and statistics */
+int uvc_debugfs_init(void);
+void uvc_debugfs_cleanup(void);
+int uvc_debugfs_init_stream(struct uvc_streaming *stream);
+void uvc_debugfs_cleanup_stream(struct uvc_streaming *stream);
+
+size_t uvc_video_stats_dump(struct uvc_streaming *stream, char *buf,
+			    size_t size);
+
 #endif
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index a5c9ed1..96e9615 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -146,10 +146,9 @@
 	struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
 
 	mutex_lock(&videodev_lock);
-	if (video_device[vdev->minor] != vdev) {
-		mutex_unlock(&videodev_lock);
+	if (WARN_ON(video_device[vdev->minor] != vdev)) {
 		/* should not happen */
-		WARN_ON(1);
+		mutex_unlock(&videodev_lock);
 		return;
 	}
 
@@ -168,7 +167,7 @@
 	mutex_unlock(&videodev_lock);
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
-	if (vdev->v4l2_dev && vdev->v4l2_dev->mdev &&
+	if (v4l2_dev && v4l2_dev->mdev &&
 	    vdev->vfl_type != VFL_TYPE_SUBDEV)
 		media_device_unregister_entity(&vdev->entity);
 #endif
@@ -556,8 +555,7 @@
 	vdev->minor = -1;
 
 	/* the release callback MUST be present */
-	WARN_ON(!vdev->release);
-	if (!vdev->release)
+	if (WARN_ON(!vdev->release))
 		return -EINVAL;
 
 	/* v4l2_fh support */
@@ -703,8 +701,8 @@
 	    vdev->vfl_type != VFL_TYPE_SUBDEV) {
 		vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
 		vdev->entity.name = vdev->name;
-		vdev->entity.v4l.major = VIDEO_MAJOR;
-		vdev->entity.v4l.minor = vdev->minor;
+		vdev->entity.info.v4l.major = VIDEO_MAJOR;
+		vdev->entity.info.v4l.minor = vdev->minor;
 		ret = media_device_register_entity(vdev->v4l2_dev->mdev,
 			&vdev->entity);
 		if (ret < 0)
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index 0edd618..1f203b8 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -234,8 +234,8 @@
 			goto clean_up;
 		}
 #if defined(CONFIG_MEDIA_CONTROLLER)
-		sd->entity.v4l.major = VIDEO_MAJOR;
-		sd->entity.v4l.minor = vdev->minor;
+		sd->entity.info.v4l.major = VIDEO_MAJOR;
+		sd->entity.info.v4l.minor = vdev->minor;
 #endif
 		sd->devnode = vdev;
 	}
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index cbf13d0..6a82875 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -156,14 +156,10 @@
 		.mbus_code	= V4L2_MBUS_FMT_YUYV8_2X8,
 		.bpp		= 2,
 	},
-	{
-		.desc		= "RGB 565",
-		.pixelformat	= V4L2_PIX_FMT_RGB565,
-		.mbus_code	= V4L2_MBUS_FMT_RGB565_2X8_LE,
-		.bpp		= 2,
-	},
 	/* RGB444 and Bayer should be doable, but have never been
-	   tested with this driver. */
+	   tested with this driver. RGB565 seems to work at the default
+	   resolution, but results in color corruption when being scaled by
+	   viacam_set_scaled(), and is disabled as a result. */
 };
 #define N_VIA_FMTS ARRAY_SIZE(via_formats)
 
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index 52a0a37..4d7391e 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -708,7 +708,7 @@
 		size, count);
 
 	/* allocate memory for table with virtual (page) addresses */
-	fb->desc_table.virtual = (unsigned long *)
+	fb->desc_table.virtual =
 		kmalloc(count * sizeof(unsigned long), GFP_KERNEL);
 	if (!fb->desc_table.virtual)
 		return -ENOMEM;
diff --git a/drivers/staging/media/as102/Kconfig b/drivers/staging/media/as102/Kconfig
index 5865029..28aba00 100644
--- a/drivers/staging/media/as102/Kconfig
+++ b/drivers/staging/media/as102/Kconfig
@@ -1,6 +1,7 @@
 config DVB_AS102
 	tristate "Abilis AS102 DVB receiver"
 	depends on DVB_CORE && USB && I2C && INPUT
+	select FW_LOADER
 	help
 	  Choose Y or M here if you have a device containing an AS102
 
diff --git a/drivers/staging/media/as102/Makefile b/drivers/staging/media/as102/Makefile
index e7dbb6f..1bca43e8 100644
--- a/drivers/staging/media/as102/Makefile
+++ b/drivers/staging/media/as102/Makefile
@@ -3,4 +3,4 @@
 
 obj-$(CONFIG_DVB_AS102) += dvb-as102.o
 
-EXTRA_CFLAGS += -DCONFIG_AS102_USB -Idrivers/media/dvb/dvb-core
+EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c
index 828526d..aae0505 100644
--- a/drivers/staging/media/as102/as102_drv.c
+++ b/drivers/staging/media/as102/as102_drv.c
@@ -24,7 +24,7 @@
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/kref.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/usb.h>
 
 /* header file for Usb device driver*/
@@ -56,13 +56,11 @@
 module_param_named(elna_enable, elna_enable, int, 0644);
 MODULE_PARM_DESC(elna_enable, "Activate eLNA (default: on)");
 
-#ifdef DVB_DEFINE_MOD_OPT_ADAPTER_NR
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-#endif
 
 static void as102_stop_stream(struct as102_dev_t *dev)
 {
-	struct as102_bus_adapter_t *bus_adap;
+	struct as10x_bus_adapter_t *bus_adap;
 
 	if (dev != NULL)
 		bus_adap = &dev->bus_adap;
@@ -85,7 +83,7 @@
 
 static int as102_start_stream(struct as102_dev_t *dev)
 {
-	struct as102_bus_adapter_t *bus_adap;
+	struct as10x_bus_adapter_t *bus_adap;
 	int ret = -EFAULT;
 
 	if (dev != NULL)
@@ -111,7 +109,7 @@
 static int as10x_pid_filter(struct as102_dev_t *dev,
 			    int index, u16 pid, int onoff) {
 
-	struct as102_bus_adapter_t *bus_adap = &dev->bus_adap;
+	struct as10x_bus_adapter_t *bus_adap = &dev->bus_adap;
 	int ret = -EFAULT;
 
 	ENTER();
@@ -123,22 +121,22 @@
 
 	switch (onoff) {
 	case 0:
-	    ret = as10x_cmd_del_PID_filter(bus_adap, (uint16_t) pid);
-	    dprintk(debug, "DEL_PID_FILTER([%02d] 0x%04x) ret = %d\n",
-		    index, pid, ret);
-	    break;
+		ret = as10x_cmd_del_PID_filter(bus_adap, (uint16_t) pid);
+		dprintk(debug, "DEL_PID_FILTER([%02d] 0x%04x) ret = %d\n",
+			index, pid, ret);
+		break;
 	case 1:
 	{
-	    struct as10x_ts_filter filter;
+		struct as10x_ts_filter filter;
 
-	    filter.type = TS_PID_TYPE_TS;
-	    filter.idx = 0xFF;
-	    filter.pid = pid;
+		filter.type = TS_PID_TYPE_TS;
+		filter.idx = 0xFF;
+		filter.pid = pid;
 
-	    ret = as10x_cmd_add_PID_filter(bus_adap, &filter);
-	    dprintk(debug, "ADD_PID_FILTER([%02d -> %02d], 0x%04x) ret = %d\n",
-		    index, filter.idx, filter.pid, ret);
-	    break;
+		ret = as10x_cmd_add_PID_filter(bus_adap, &filter);
+		dprintk(debug, "ADD_PID_FILTER([%02d -> %02d], 0x%04x) ret = %d\n",
+			index, filter.idx, filter.pid, ret);
+		break;
 	}
 	}
 
@@ -159,10 +157,9 @@
 	if (mutex_lock_interruptible(&as102_dev->sem))
 		return -ERESTARTSYS;
 
-	if (pid_filtering) {
-		as10x_pid_filter(as102_dev,
-				dvbdmxfeed->index, dvbdmxfeed->pid, 1);
-	}
+	if (pid_filtering)
+		as10x_pid_filter(as102_dev, dvbdmxfeed->index,
+				 dvbdmxfeed->pid, 1);
 
 	if (as102_dev->streaming++ == 0)
 		ret = as102_start_stream(as102_dev);
@@ -185,10 +182,9 @@
 	if (--as102_dev->streaming == 0)
 		as102_stop_stream(as102_dev);
 
-	if (pid_filtering) {
-		as10x_pid_filter(as102_dev,
-				dvbdmxfeed->index, dvbdmxfeed->pid, 0);
-	}
+	if (pid_filtering)
+		as10x_pid_filter(as102_dev, dvbdmxfeed->index,
+				 dvbdmxfeed->pid, 0);
 
 	mutex_unlock(&as102_dev->sem);
 	LEAVE();
@@ -197,27 +193,16 @@
 
 int as102_dvb_register(struct as102_dev_t *as102_dev)
 {
-	int ret = 0;
-	ENTER();
+	struct device *dev = &as102_dev->bus_adap.usb_dev->dev;
+	int ret;
 
 	ret = dvb_register_adapter(&as102_dev->dvb_adap,
-				   as102_dev->name,
-				   THIS_MODULE,
-#if defined(CONFIG_AS102_USB)
-				   &as102_dev->bus_adap.usb_dev->dev
-#elif defined(CONFIG_AS102_SPI)
-				   &as102_dev->bus_adap.spi_dev->dev
-#else
-#error >>> dvb_register_adapter <<<
-#endif
-#ifdef DVB_DEFINE_MOD_OPT_ADAPTER_NR
-				   , adapter_nr
-#endif
-				   );
+			   as102_dev->name, THIS_MODULE,
+			   dev, adapter_nr);
 	if (ret < 0) {
-		err("%s: dvb_register_adapter() failed (errno = %d)",
-		    __func__, ret);
-		goto failed;
+		dev_err(dev, "%s: dvb_register_adapter() failed: %d\n",
+			__func__, ret);
+		return ret;
 	}
 
 	as102_dev->dvb_dmx.priv = as102_dev;
@@ -235,22 +220,22 @@
 
 	ret = dvb_dmx_init(&as102_dev->dvb_dmx);
 	if (ret < 0) {
-		err("%s: dvb_dmx_init() failed (errno = %d)", __func__, ret);
-		goto failed;
+		dev_err(dev, "%s: dvb_dmx_init() failed: %d\n", __func__, ret);
+		goto edmxinit;
 	}
 
 	ret = dvb_dmxdev_init(&as102_dev->dvb_dmxdev, &as102_dev->dvb_adap);
 	if (ret < 0) {
-		err("%s: dvb_dmxdev_init() failed (errno = %d)", __func__,
-		    ret);
-		goto failed;
+		dev_err(dev, "%s: dvb_dmxdev_init() failed: %d\n",
+			__func__, ret);
+		goto edmxdinit;
 	}
 
 	ret = as102_dvb_register_fe(as102_dev, &as102_dev->dvb_fe);
 	if (ret < 0) {
-		err("%s: as102_dvb_register_frontend() failed (errno = %d)",
+		dev_err(dev, "%s: as102_dvb_register_frontend() failed: %d",
 		    __func__, ret);
-		goto failed;
+		goto efereg;
 	}
 
 	/* init bus mutex for token locking */
@@ -259,7 +244,6 @@
 	/* init start / stop stream mutex */
 	mutex_init(&as102_dev->sem);
 
-#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
 	/*
 	 * try to load as102 firmware. If firmware upload failed, we'll be
 	 * able to upload it later.
@@ -267,18 +251,21 @@
 	if (fw_upload)
 		try_then_request_module(as102_fw_upload(&as102_dev->bus_adap),
 				"firmware_class");
-#endif
 
-failed:
-	LEAVE();
-	/* FIXME: free dvb_XXX */
+	pr_info("Registered device %s", as102_dev->name);
+	return 0;
+
+efereg:
+	dvb_dmxdev_release(&as102_dev->dvb_dmxdev);
+edmxdinit:
+	dvb_dmx_release(&as102_dev->dvb_dmx);
+edmxinit:
+	dvb_unregister_adapter(&as102_dev->dvb_adap);
 	return ret;
 }
 
 void as102_dvb_unregister(struct as102_dev_t *as102_dev)
 {
-	ENTER();
-
 	/* unregister as102 frontend */
 	as102_dvb_unregister_fe(&as102_dev->dvb_fe);
 
@@ -289,28 +276,18 @@
 	/* unregister dvb adapter */
 	dvb_unregister_adapter(&as102_dev->dvb_adap);
 
-	LEAVE();
+	pr_info("Unregistered device %s", as102_dev->name);
 }
 
 static int __init as102_driver_init(void)
 {
-	int ret = 0;
-
-	ENTER();
+	int ret;
 
 	/* register this driver with the low level subsystem */
-#if defined(CONFIG_AS102_USB)
 	ret = usb_register(&as102_usb_driver);
 	if (ret)
 		err("usb_register failed (ret = %d)", ret);
-#endif
-#if defined(CONFIG_AS102_SPI)
-	ret = spi_register_driver(&as102_spi_driver);
-	if (ret)
-		printk(KERN_ERR "spi_register failed (ret = %d)", ret);
-#endif
 
-	LEAVE();
 	return ret;
 }
 
@@ -327,15 +304,8 @@
  */
 static void __exit as102_driver_exit(void)
 {
-	ENTER();
 	/* deregister this driver with the low level bus subsystem */
-#if defined(CONFIG_AS102_USB)
 	usb_deregister(&as102_usb_driver);
-#endif
-#if defined(CONFIG_AS102_SPI)
-	spi_unregister_driver(&as102_spi_driver);
-#endif
-	LEAVE();
 }
 
 /*
@@ -347,5 +317,3 @@
 MODULE_DESCRIPTION(DRIVER_FULL_NAME);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Pierrick Hascoet <pierrick.hascoet@abilis.com>");
-
-/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_drv.h b/drivers/staging/media/as102/as102_drv.h
index fd33f5a..957f0ed 100644
--- a/drivers/staging/media/as102/as102_drv.h
+++ b/drivers/staging/media/as102/as102_drv.h
@@ -17,38 +17,30 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#if defined(CONFIG_AS102_USB)
 #include <linux/usb.h>
-extern struct usb_driver as102_usb_driver;
-#endif
-
-#if defined(CONFIG_AS102_SPI)
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/cdev.h>
-
-extern struct spi_driver as102_spi_driver;
-#endif
-
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dmxdev.h"
+#include <dvb_demux.h>
+#include <dvb_frontend.h>
+#include <dmxdev.h>
+#include "as10x_cmd.h"
+#include "as102_usb_drv.h"
 
 #define DRIVER_FULL_NAME "Abilis Systems as10x usb driver"
 #define DRIVER_NAME "as10x_usb"
 
 extern int as102_debug;
 #define debug	as102_debug
+extern struct usb_driver as102_usb_driver;
+extern int elna_enable;
 
 #define dprintk(debug, args...) \
 	do { if (debug) {	\
-		printk(KERN_DEBUG "%s: ",__FUNCTION__);	\
+		pr_debug("%s: ", __func__);	\
 		printk(args);	\
 	} } while (0)
 
 #ifdef TRACE
-#define ENTER()                 printk(">> enter %s\n", __FUNCTION__)
-#define LEAVE()                 printk("<< leave %s\n", __FUNCTION__)
+#define ENTER()	pr_debug(">> enter %s\n", __func__)
+#define LEAVE()	pr_debug("<< leave %s\n", __func__)
 #else
 #define ENTER()
 #define LEAVE()
@@ -59,39 +51,14 @@
 #define AS102_USB_BUF_SIZE	512
 #define MAX_STREAM_URB		32
 
-#include "as10x_cmd.h"
-
-#if defined(CONFIG_AS102_USB)
-#include "as102_usb_drv.h"
-#endif
-
-#if defined(CONFIG_AS102_SPI)
-#include "as10x_spi_drv.h"
-#endif
-
-
-struct as102_bus_adapter_t {
-#if defined(CONFIG_AS102_USB)
+struct as10x_bus_adapter_t {
 	struct usb_device *usb_dev;
-#elif defined(CONFIG_AS102_SPI)
-	struct spi_device *spi_dev;
-	struct cdev cdev; /* spidev raw device */
-
-	struct timer_list timer;
-	struct completion xfer_done;
-#endif
 	/* bus token lock */
 	struct mutex lock;
 	/* low level interface for bus adapter */
 	union as10x_bus_token_t {
-#if defined(CONFIG_AS102_USB)
 		/* usb token */
 		struct as10x_usb_token_cmd_t usb;
-#endif
-#if defined(CONFIG_AS102_SPI)
-		/* spi token */
-		struct as10x_spi_token_cmd_t spi;
-#endif
 	} token;
 
 	/* token cmd xfer id */
@@ -106,7 +73,7 @@
 
 struct as102_dev_t {
 	const char *name;
-	struct as102_bus_adapter_t bus_adap;
+	struct as10x_bus_adapter_t bus_adap;
 	struct list_head device_entry;
 	struct kref kref;
 	unsigned long minor;
@@ -138,5 +105,3 @@
 
 int as102_dvb_register_fe(struct as102_dev_t *dev, struct dvb_frontend *fe);
 int as102_dvb_unregister_fe(struct dvb_frontend *dev);
-
-/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_fe.c b/drivers/staging/media/as102/as102_fe.c
index 3550f90..c2adfe5 100644
--- a/drivers/staging/media/as102/as102_fe.c
+++ b/drivers/staging/media/as102/as102_fe.c
@@ -23,8 +23,6 @@
 #include "as10x_types.h"
 #include "as10x_cmd.h"
 
-extern int elna_enable;
-
 static void as10x_fe_copy_tps_parameters(struct dvb_frontend_parameters *dst,
 					 struct as10x_tps *src);
 
@@ -599,5 +597,3 @@
 			as102_fe_get_code_rate(params->u.ofdm.code_rate_HP);
 	}
 }
-
-/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_fw.c b/drivers/staging/media/as102/as102_fw.c
index c019df9..43ebc43 100644
--- a/drivers/staging/media/as102/as102_fw.c
+++ b/drivers/staging/media/as102/as102_fw.c
@@ -26,7 +26,6 @@
 #include "as102_drv.h"
 #include "as102_fw.h"
 
-#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
 char as102_st_fw1[] = "as102_data1_st.hex";
 char as102_st_fw2[] = "as102_data2_st.hex";
 char as102_dt_fw1[] = "as102_data1_dt.hex";
@@ -59,7 +58,7 @@
 	unsigned char *src, dst;
 
 	if (*fw_data++ != ':') {
-		printk(KERN_ERR "invalid firmware file\n");
+		pr_err("invalid firmware file\n");
 		return -EFAULT;
 	}
 
@@ -102,7 +101,7 @@
 	return (count * 2) + 2;
 }
 
-static int as102_firmware_upload(struct as102_bus_adapter_t *bus_adap,
+static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap,
 				 unsigned char *cmd,
 				 const struct firmware *firmware) {
 
@@ -163,19 +162,14 @@
 	return (errno == 0) ? total_read_bytes : errno;
 }
 
-int as102_fw_upload(struct as102_bus_adapter_t *bus_adap)
+int as102_fw_upload(struct as10x_bus_adapter_t *bus_adap)
 {
 	int errno = -EFAULT;
 	const struct firmware *firmware;
 	unsigned char *cmd_buf = NULL;
 	char *fw1, *fw2;
-
-#if defined(CONFIG_AS102_USB)
 	struct usb_device *dev = bus_adap->usb_dev;
-#endif
-#if defined(CONFIG_AS102_SPI)
-	struct spi_device *dev = bus_adap->spi_dev;
-#endif
+
 	ENTER();
 
 	/* select fw file to upload */
@@ -187,7 +181,6 @@
 		fw2 = as102_st_fw2;
 	}
 
-#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
 	/* allocate buffer to store firmware upload command and data */
 	cmd_buf = kzalloc(MAX_FW_PKT_SIZE, GFP_KERNEL);
 	if (cmd_buf == NULL) {
@@ -198,21 +191,21 @@
 	/* request kernel to locate firmware file: part1 */
 	errno = request_firmware(&firmware, fw1, &dev->dev);
 	if (errno < 0) {
-		printk(KERN_ERR "%s: unable to locate firmware file: %s\n",
-				 DRIVER_NAME, fw1);
+		pr_err("%s: unable to locate firmware file: %s\n",
+		       DRIVER_NAME, fw1);
 		goto error;
 	}
 
 	/* initiate firmware upload */
 	errno = as102_firmware_upload(bus_adap, cmd_buf, firmware);
 	if (errno < 0) {
-		printk(KERN_ERR "%s: error during firmware upload part1\n",
-				 DRIVER_NAME);
+		pr_err("%s: error during firmware upload part1\n",
+		       DRIVER_NAME);
 		goto error;
 	}
 
-	printk(KERN_INFO "%s: fimrware: %s loaded with success\n",
-			 DRIVER_NAME, fw1);
+	pr_info("%s: firmware: %s loaded with success\n",
+		DRIVER_NAME, fw1);
 	release_firmware(firmware);
 
 	/* wait for boot to complete */
@@ -221,31 +214,28 @@
 	/* request kernel to locate firmware file: part2 */
 	errno = request_firmware(&firmware, fw2, &dev->dev);
 	if (errno < 0) {
-		printk(KERN_ERR "%s: unable to locate firmware file: %s\n",
-				 DRIVER_NAME, fw2);
+		pr_err("%s: unable to locate firmware file: %s\n",
+		       DRIVER_NAME, fw2);
 		goto error;
 	}
 
 	/* initiate firmware upload */
 	errno = as102_firmware_upload(bus_adap, cmd_buf, firmware);
 	if (errno < 0) {
-		printk(KERN_ERR "%s: error during firmware upload part2\n",
-				 DRIVER_NAME);
+		pr_err("%s: error during firmware upload part2\n",
+		       DRIVER_NAME);
 		goto error;
 	}
 
-	printk(KERN_INFO "%s: fimrware: %s loaded with success\n",
-			DRIVER_NAME, fw2);
+	pr_info("%s: firmware: %s loaded with success\n",
+		DRIVER_NAME, fw2);
 error:
 	/* free data buffer */
 	kfree(cmd_buf);
 	/* release firmware if needed */
 	if (firmware != NULL)
 		release_firmware(firmware);
-#endif
+
 	LEAVE();
 	return errno;
 }
-#endif
-
-/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_fw.h b/drivers/staging/media/as102/as102_fw.h
index 27e5347..bd21f05 100644
--- a/drivers/staging/media/as102/as102_fw.h
+++ b/drivers/staging/media/as102/as102_fw.h
@@ -20,11 +20,10 @@
 
 extern int dual_tuner;
 
-#pragma pack(1)
 struct as10x_raw_fw_pkt {
 	unsigned char address[4];
 	unsigned char data[MAX_FW_PKT_SIZE - 6];
-};
+} __packed;
 
 struct as10x_fw_pkt_t {
 	union {
@@ -32,11 +31,8 @@
 		unsigned char length[2];
 	} u;
 	struct as10x_raw_fw_pkt raw;
-};
-#pragma pack()
+} __packed;
 
 #ifdef __KERNEL__
-int as102_fw_upload(struct as102_bus_adapter_t *bus_adap);
+int as102_fw_upload(struct as10x_bus_adapter_t *bus_adap);
 #endif
-
-/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_usb_drv.c b/drivers/staging/media/as102/as102_usb_drv.c
index 264be2d..7bcb28c 100644
--- a/drivers/staging/media/as102/as102_usb_drv.c
+++ b/drivers/staging/media/as102/as102_usb_drv.c
@@ -42,30 +42,32 @@
 	{ USB_DEVICE(PCTV_74E_USB_VID, PCTV_74E_USB_PID) },
 	{ USB_DEVICE(ELGATO_EYETV_DTT_USB_VID, ELGATO_EYETV_DTT_USB_PID) },
 	{ USB_DEVICE(NBOX_DVBT_DONGLE_USB_VID, NBOX_DVBT_DONGLE_USB_PID) },
+	{ USB_DEVICE(SKY_IT_DIGITAL_KEY_USB_VID, SKY_IT_DIGITAL_KEY_USB_PID) },
 	{ } /* Terminating entry */
 };
 
 /* Note that this table must always have the same number of entries as the
    as102_usb_id_table struct */
-static const char *as102_device_names[] = {
+static const char * const as102_device_names[] = {
 	AS102_REFERENCE_DESIGN,
 	AS102_PCTV_74E,
 	AS102_ELGATO_EYETV_DTT_NAME,
 	AS102_NBOX_DVBT_DONGLE_NAME,
+	AS102_SKY_IT_DIGITAL_KEY_NAME,
 	NULL /* Terminating entry */
 };
 
 struct usb_driver as102_usb_driver = {
-	.name       =  DRIVER_FULL_NAME,
-	.probe      =  as102_usb_probe,
-	.disconnect =  as102_usb_disconnect,
-	.id_table   =  as102_usb_id_table
+	.name		= DRIVER_FULL_NAME,
+	.probe		= as102_usb_probe,
+	.disconnect	= as102_usb_disconnect,
+	.id_table	= as102_usb_id_table
 };
 
 static const struct file_operations as102_dev_fops = {
-	.owner   = THIS_MODULE,
-	.open    = as102_open,
-	.release = as102_release,
+	.owner		= THIS_MODULE,
+	.open		= as102_open,
+	.release	= as102_release,
 };
 
 static struct usb_class_driver as102_usb_class_driver = {
@@ -74,7 +76,7 @@
 	.minor_base	= AS102_DEVICE_MAJOR,
 };
 
-static int as102_usb_xfer_cmd(struct as102_bus_adapter_t *bus_adap,
+static int as102_usb_xfer_cmd(struct as10x_bus_adapter_t *bus_adap,
 			      unsigned char *send_buf, int send_buf_len,
 			      unsigned char *recv_buf, int recv_buf_len)
 {
@@ -131,7 +133,7 @@
 	return ret;
 }
 
-static int as102_send_ep1(struct as102_bus_adapter_t *bus_adap,
+static int as102_send_ep1(struct as10x_bus_adapter_t *bus_adap,
 			  unsigned char *send_buf,
 			  int send_buf_len,
 			  int swap32)
@@ -154,7 +156,7 @@
 	return ret ? ret : actual_len;
 }
 
-static int as102_read_ep2(struct as102_bus_adapter_t *bus_adap,
+static int as102_read_ep2(struct as10x_bus_adapter_t *bus_adap,
 		   unsigned char *recv_buf, int recv_buf_len)
 {
 	int ret = 0, actual_len;
@@ -337,7 +339,7 @@
 	/* decrement usage counter */
 	kref_put(&as102_dev->kref, as102_usb_release);
 
-	printk(KERN_INFO "%s: device has been disconnected\n", DRIVER_NAME);
+	pr_info("%s: device has been disconnected\n", DRIVER_NAME);
 
 	LEAVE();
 }
@@ -360,7 +362,7 @@
 	/* This should never actually happen */
 	if ((sizeof(as102_usb_id_table) / sizeof(struct usb_device_id)) !=
 	    (sizeof(as102_device_names) / sizeof(const char *))) {
-		printk(KERN_ERR "Device names table invalid size");
+		pr_err("Device names table invalid size");
 		return -EINVAL;
 	}
 
@@ -399,7 +401,7 @@
 		goto failed;
 	}
 
-	printk(KERN_INFO "%s: device has been detected\n", DRIVER_NAME);
+	pr_info("%s: device has been detected\n", DRIVER_NAME);
 
 	/* request buffer allocation for streaming */
 	ret = as102_alloc_usb_stream_buffer(as102_dev);
@@ -432,8 +434,8 @@
 	/* fetch device from usb interface */
 	intf = usb_find_interface(&as102_usb_driver, minor);
 	if (intf == NULL) {
-		printk(KERN_ERR "%s: can't find device for minor %d\n",
-				__func__, minor);
+		pr_err("%s: can't find device for minor %d\n",
+		       __func__, minor);
 		ret = -ENODEV;
 		goto exit;
 	}
@@ -474,5 +476,3 @@
 }
 
 MODULE_DEVICE_TABLE(usb, as102_usb_id_table);
-
-/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_usb_drv.h b/drivers/staging/media/as102/as102_usb_drv.h
index fb1fc41..fc2884a 100644
--- a/drivers/staging/media/as102/as102_usb_drv.h
+++ b/drivers/staging/media/as102/as102_usb_drv.h
@@ -47,6 +47,11 @@
 #define NBOX_DVBT_DONGLE_USB_VID	0x0b89
 #define NBOX_DVBT_DONGLE_USB_PID	0x0007
 
+/* Sky Italia: Digital Key (green led) */
+#define AS102_SKY_IT_DIGITAL_KEY_NAME	"Sky IT Digital Key (green led)"
+#define SKY_IT_DIGITAL_KEY_USB_VID	0x2137
+#define SKY_IT_DIGITAL_KEY_USB_PID	0x0001
+
 void as102_urb_stream_irq(struct urb *urb);
 
 struct as10x_usb_token_cmd_t {
@@ -56,4 +61,3 @@
 	struct as10x_cmd_t r;
 };
 #endif
-/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as10x_cmd.c b/drivers/staging/media/as102/as10x_cmd.c
index 0dcba80..0387bb8 100644
--- a/drivers/staging/media/as102/as10x_cmd.c
+++ b/drivers/staging/media/as102/as10x_cmd.c
@@ -25,35 +25,35 @@
 
 /**
  * as10x_cmd_turn_on - send turn on command to AS10x
- * @phandle:   pointer to AS10x handle
+ * @adap:   pointer to AS10x bus adapter
  *
  * Return 0 when no error, < 0 in case of error.
  */
-int as10x_cmd_turn_on(as10x_handle_t *phandle)
+int as10x_cmd_turn_on(struct as10x_bus_adapter_t *adap)
 {
 	int error;
 	struct as10x_cmd_t *pcmd, *prsp;
 
 	ENTER();
 
-	pcmd = phandle->cmd;
-	prsp = phandle->rsp;
+	pcmd = adap->cmd;
+	prsp = adap->rsp;
 
 	/* prepare command */
-	as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+	as10x_cmd_build(pcmd, (++adap->cmd_xid),
 			sizeof(pcmd->body.turn_on.req));
 
 	/* fill command */
 	pcmd->body.turn_on.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNON);
 
 	/* send command */
-	if (phandle->ops->xfer_cmd) {
-		error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
-					       sizeof(pcmd->body.turn_on.req) +
-					       HEADER_SIZE,
-					       (uint8_t *) prsp,
-					       sizeof(prsp->body.turn_on.rsp) +
-					       HEADER_SIZE);
+	if (adap->ops->xfer_cmd) {
+		error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
+					    sizeof(pcmd->body.turn_on.req) +
+					    HEADER_SIZE,
+					    (uint8_t *) prsp,
+					    sizeof(prsp->body.turn_on.rsp) +
+					    HEADER_SIZE);
 	} else {
 		error = AS10X_CMD_ERROR;
 	}
@@ -71,31 +71,31 @@
 
 /**
  * as10x_cmd_turn_off - send turn off command to AS10x
- * @phandle:   pointer to AS10x handle
+ * @adap:   pointer to AS10x bus adapter
  *
  * Return 0 on success or negative value in case of error.
  */
-int as10x_cmd_turn_off(as10x_handle_t *phandle)
+int as10x_cmd_turn_off(struct as10x_bus_adapter_t *adap)
 {
 	int error;
 	struct as10x_cmd_t *pcmd, *prsp;
 
 	ENTER();
 
-	pcmd = phandle->cmd;
-	prsp = phandle->rsp;
+	pcmd = adap->cmd;
+	prsp = adap->rsp;
 
 	/* prepare command */
-	as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+	as10x_cmd_build(pcmd, (++adap->cmd_xid),
 			sizeof(pcmd->body.turn_off.req));
 
 	/* fill command */
 	pcmd->body.turn_off.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNOFF);
 
 	/* send command */
-	if (phandle->ops->xfer_cmd) {
-		error = phandle->ops->xfer_cmd(
-			phandle, (uint8_t *) pcmd,
+	if (adap->ops->xfer_cmd) {
+		error = adap->ops->xfer_cmd(
+			adap, (uint8_t *) pcmd,
 			sizeof(pcmd->body.turn_off.req) + HEADER_SIZE,
 			(uint8_t *) prsp,
 			sizeof(prsp->body.turn_off.rsp) + HEADER_SIZE);
@@ -116,23 +116,24 @@
 
 /**
  * as10x_cmd_set_tune - send set tune command to AS10x
- * @phandle: pointer to AS10x handle
+ * @adap:    pointer to AS10x bus adapter
  * @ptune:   tune parameters
  *
  * Return 0 on success or negative value in case of error.
  */
-int as10x_cmd_set_tune(as10x_handle_t *phandle, struct as10x_tune_args *ptune)
+int as10x_cmd_set_tune(struct as10x_bus_adapter_t *adap,
+		       struct as10x_tune_args *ptune)
 {
 	int error;
 	struct as10x_cmd_t *preq, *prsp;
 
 	ENTER();
 
-	preq = phandle->cmd;
-	prsp = phandle->rsp;
+	preq = adap->cmd;
+	prsp = adap->rsp;
 
 	/* prepare command */
-	as10x_cmd_build(preq, (++phandle->cmd_xid),
+	as10x_cmd_build(preq, (++adap->cmd_xid),
 			sizeof(preq->body.set_tune.req));
 
 	/* fill command */
@@ -150,14 +151,14 @@
 		ptune->transmission_mode;
 
 	/* send command */
-	if (phandle->ops->xfer_cmd) {
-		error = phandle->ops->xfer_cmd(phandle,
-					       (uint8_t *) preq,
-					       sizeof(preq->body.set_tune.req)
-					       + HEADER_SIZE,
-					       (uint8_t *) prsp,
-					       sizeof(prsp->body.set_tune.rsp)
-					       + HEADER_SIZE);
+	if (adap->ops->xfer_cmd) {
+		error = adap->ops->xfer_cmd(adap,
+					    (uint8_t *) preq,
+					    sizeof(preq->body.set_tune.req)
+					    + HEADER_SIZE,
+					    (uint8_t *) prsp,
+					    sizeof(prsp->body.set_tune.rsp)
+					    + HEADER_SIZE);
 	} else {
 		error = AS10X_CMD_ERROR;
 	}
@@ -175,12 +176,12 @@
 
 /**
  * as10x_cmd_get_tune_status - send get tune status command to AS10x
- * @phandle: pointer to AS10x handle
+ * @adap: pointer to AS10x bus adapter
  * @pstatus: pointer to updated status structure of the current tune
  *
  * Return 0 on success or negative value in case of error.
  */
-int as10x_cmd_get_tune_status(as10x_handle_t *phandle,
+int as10x_cmd_get_tune_status(struct as10x_bus_adapter_t *adap,
 			      struct as10x_tune_status *pstatus)
 {
 	int error;
@@ -188,11 +189,11 @@
 
 	ENTER();
 
-	preq = phandle->cmd;
-	prsp = phandle->rsp;
+	preq = adap->cmd;
+	prsp = adap->rsp;
 
 	/* prepare command */
-	as10x_cmd_build(preq, (++phandle->cmd_xid),
+	as10x_cmd_build(preq, (++adap->cmd_xid),
 			sizeof(preq->body.get_tune_status.req));
 
 	/* fill command */
@@ -200,9 +201,9 @@
 		cpu_to_le16(CONTROL_PROC_GETTUNESTAT);
 
 	/* send command */
-	if (phandle->ops->xfer_cmd) {
-		error = phandle->ops->xfer_cmd(
-			phandle,
+	if (adap->ops->xfer_cmd) {
+		error = adap->ops->xfer_cmd(
+			adap,
 			(uint8_t *) preq,
 			sizeof(preq->body.get_tune_status.req) + HEADER_SIZE,
 			(uint8_t *) prsp,
@@ -232,24 +233,24 @@
 }
 
 /**
- * send get TPS command to AS10x
- * @phandle:   pointer to AS10x handle
+ * as10x_cmd_get_tps - send get TPS command to AS10x
+ * @adap:      pointer to AS10x handle
  * @ptps:      pointer to TPS parameters structure
  *
  * Return 0 on success or negative value in case of error.
  */
-int as10x_cmd_get_tps(as10x_handle_t *phandle, struct as10x_tps *ptps)
+int as10x_cmd_get_tps(struct as10x_bus_adapter_t *adap, struct as10x_tps *ptps)
 {
 	int error;
 	struct as10x_cmd_t *pcmd, *prsp;
 
 	ENTER();
 
-	pcmd = phandle->cmd;
-	prsp = phandle->rsp;
+	pcmd = adap->cmd;
+	prsp = adap->rsp;
 
 	/* prepare command */
-	as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+	as10x_cmd_build(pcmd, (++adap->cmd_xid),
 			sizeof(pcmd->body.get_tps.req));
 
 	/* fill command */
@@ -257,14 +258,14 @@
 		cpu_to_le16(CONTROL_PROC_GETTPS);
 
 	/* send command */
-	if (phandle->ops->xfer_cmd) {
-		error = phandle->ops->xfer_cmd(phandle,
-					       (uint8_t *) pcmd,
-					       sizeof(pcmd->body.get_tps.req) +
-					       HEADER_SIZE,
-					       (uint8_t *) prsp,
-					       sizeof(prsp->body.get_tps.rsp) +
-					       HEADER_SIZE);
+	if (adap->ops->xfer_cmd) {
+		error = adap->ops->xfer_cmd(adap,
+					    (uint8_t *) pcmd,
+					    sizeof(pcmd->body.get_tps.req) +
+					    HEADER_SIZE,
+					    (uint8_t *) prsp,
+					    sizeof(prsp->body.get_tps.rsp) +
+					    HEADER_SIZE);
 	} else {
 		error = AS10X_CMD_ERROR;
 	}
@@ -296,12 +297,12 @@
 
 /**
  * as10x_cmd_get_demod_stats - send get demod stats command to AS10x
- * @phandle:       pointer to AS10x handle
+ * @adap:          pointer to AS10x bus adapter
  * @pdemod_stats:  pointer to demod stats parameters structure
  *
  * Return 0 on success or negative value in case of error.
  */
-int as10x_cmd_get_demod_stats(as10x_handle_t  *phandle,
+int as10x_cmd_get_demod_stats(struct as10x_bus_adapter_t *adap,
 			      struct as10x_demod_stats *pdemod_stats)
 {
 	int error;
@@ -309,11 +310,11 @@
 
 	ENTER();
 
-	pcmd = phandle->cmd;
-	prsp = phandle->rsp;
+	pcmd = adap->cmd;
+	prsp = adap->rsp;
 
 	/* prepare command */
-	as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+	as10x_cmd_build(pcmd, (++adap->cmd_xid),
 			sizeof(pcmd->body.get_demod_stats.req));
 
 	/* fill command */
@@ -321,8 +322,8 @@
 		cpu_to_le16(CONTROL_PROC_GET_DEMOD_STATS);
 
 	/* send command */
-	if (phandle->ops->xfer_cmd) {
-		error = phandle->ops->xfer_cmd(phandle,
+	if (adap->ops->xfer_cmd) {
+		error = adap->ops->xfer_cmd(adap,
 				(uint8_t *) pcmd,
 				sizeof(pcmd->body.get_demod_stats.req)
 				+ HEADER_SIZE,
@@ -360,13 +361,13 @@
 
 /**
  * as10x_cmd_get_impulse_resp - send get impulse response command to AS10x
- * @phandle:  pointer to AS10x handle
+ * @adap:     pointer to AS10x bus adapter
  * @is_ready: pointer to value indicating when impulse
  *	      response data is ready
  *
  * Return 0 on success or negative value in case of error.
  */
-int as10x_cmd_get_impulse_resp(as10x_handle_t     *phandle,
+int as10x_cmd_get_impulse_resp(struct as10x_bus_adapter_t *adap,
 			       uint8_t *is_ready)
 {
 	int error;
@@ -374,11 +375,11 @@
 
 	ENTER();
 
-	pcmd = phandle->cmd;
-	prsp = phandle->rsp;
+	pcmd = adap->cmd;
+	prsp = adap->rsp;
 
 	/* prepare command */
-	as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+	as10x_cmd_build(pcmd, (++adap->cmd_xid),
 			sizeof(pcmd->body.get_impulse_rsp.req));
 
 	/* fill command */
@@ -386,8 +387,8 @@
 		cpu_to_le16(CONTROL_PROC_GET_IMPULSE_RESP);
 
 	/* send command */
-	if (phandle->ops->xfer_cmd) {
-		error = phandle->ops->xfer_cmd(phandle,
+	if (adap->ops->xfer_cmd) {
+		error = adap->ops->xfer_cmd(adap,
 					(uint8_t *) pcmd,
 					sizeof(pcmd->body.get_impulse_rsp.req)
 					+ HEADER_SIZE,
diff --git a/drivers/staging/media/as102/as10x_cmd.h b/drivers/staging/media/as102/as10x_cmd.h
index 01a7163..4ea249e 100644
--- a/drivers/staging/media/as102/as10x_cmd.h
+++ b/drivers/staging/media/as102/as10x_cmd.h
@@ -28,459 +28,456 @@
 /*********************************/
 /*       MACRO DEFINITIONS       */
 /*********************************/
-#define AS10X_CMD_ERROR -1
+#define AS10X_CMD_ERROR		-1
 
-#define SERVICE_PROG_ID        0x0002
-#define SERVICE_PROG_VERSION   0x0001
+#define SERVICE_PROG_ID		0x0002
+#define SERVICE_PROG_VERSION	0x0001
 
-#define HIER_NONE              0x00
-#define HIER_LOW_PRIORITY      0x01
+#define HIER_NONE		0x00
+#define HIER_LOW_PRIORITY	0x01
 
 #define HEADER_SIZE (sizeof(struct as10x_cmd_header_t))
 
 /* context request types */
-#define GET_CONTEXT_DATA        1
-#define SET_CONTEXT_DATA        2
+#define GET_CONTEXT_DATA	1
+#define SET_CONTEXT_DATA	2
 
 /* ODSP suspend modes */
-#define CFG_MODE_ODSP_RESUME  0
-#define CFG_MODE_ODSP_SUSPEND 1
+#define CFG_MODE_ODSP_RESUME	0
+#define CFG_MODE_ODSP_SUSPEND	1
 
 /* Dump memory size */
-#define DUMP_BLOCK_SIZE_MAX   0x20
+#define DUMP_BLOCK_SIZE_MAX	0x20
 
 /*********************************/
 /*     TYPE DEFINITION           */
 /*********************************/
-typedef enum {
-   CONTROL_PROC_TURNON               = 0x0001,
-   CONTROL_PROC_TURNON_RSP           = 0x0100,
-   CONTROL_PROC_SET_REGISTER         = 0x0002,
-   CONTROL_PROC_SET_REGISTER_RSP     = 0x0200,
-   CONTROL_PROC_GET_REGISTER         = 0x0003,
-   CONTROL_PROC_GET_REGISTER_RSP     = 0x0300,
-   CONTROL_PROC_SETTUNE              = 0x000A,
-   CONTROL_PROC_SETTUNE_RSP          = 0x0A00,
-   CONTROL_PROC_GETTUNESTAT          = 0x000B,
-   CONTROL_PROC_GETTUNESTAT_RSP      = 0x0B00,
-   CONTROL_PROC_GETTPS               = 0x000D,
-   CONTROL_PROC_GETTPS_RSP           = 0x0D00,
-   CONTROL_PROC_SETFILTER            = 0x000E,
-   CONTROL_PROC_SETFILTER_RSP        = 0x0E00,
-   CONTROL_PROC_REMOVEFILTER         = 0x000F,
-   CONTROL_PROC_REMOVEFILTER_RSP     = 0x0F00,
-   CONTROL_PROC_GET_IMPULSE_RESP     = 0x0012,
-   CONTROL_PROC_GET_IMPULSE_RESP_RSP = 0x1200,
-   CONTROL_PROC_START_STREAMING      = 0x0013,
-   CONTROL_PROC_START_STREAMING_RSP  = 0x1300,
-   CONTROL_PROC_STOP_STREAMING       = 0x0014,
-   CONTROL_PROC_STOP_STREAMING_RSP   = 0x1400,
-   CONTROL_PROC_GET_DEMOD_STATS      = 0x0015,
-   CONTROL_PROC_GET_DEMOD_STATS_RSP  = 0x1500,
-   CONTROL_PROC_ELNA_CHANGE_MODE     = 0x0016,
-   CONTROL_PROC_ELNA_CHANGE_MODE_RSP = 0x1600,
-   CONTROL_PROC_ODSP_CHANGE_MODE     = 0x0017,
-   CONTROL_PROC_ODSP_CHANGE_MODE_RSP = 0x1700,
-   CONTROL_PROC_AGC_CHANGE_MODE      = 0x0018,
-   CONTROL_PROC_AGC_CHANGE_MODE_RSP  = 0x1800,
+enum control_proc {
+	CONTROL_PROC_TURNON			= 0x0001,
+	CONTROL_PROC_TURNON_RSP			= 0x0100,
+	CONTROL_PROC_SET_REGISTER		= 0x0002,
+	CONTROL_PROC_SET_REGISTER_RSP		= 0x0200,
+	CONTROL_PROC_GET_REGISTER		= 0x0003,
+	CONTROL_PROC_GET_REGISTER_RSP		= 0x0300,
+	CONTROL_PROC_SETTUNE			= 0x000A,
+	CONTROL_PROC_SETTUNE_RSP		= 0x0A00,
+	CONTROL_PROC_GETTUNESTAT		= 0x000B,
+	CONTROL_PROC_GETTUNESTAT_RSP		= 0x0B00,
+	CONTROL_PROC_GETTPS			= 0x000D,
+	CONTROL_PROC_GETTPS_RSP			= 0x0D00,
+	CONTROL_PROC_SETFILTER			= 0x000E,
+	CONTROL_PROC_SETFILTER_RSP		= 0x0E00,
+	CONTROL_PROC_REMOVEFILTER		= 0x000F,
+	CONTROL_PROC_REMOVEFILTER_RSP		= 0x0F00,
+	CONTROL_PROC_GET_IMPULSE_RESP		= 0x0012,
+	CONTROL_PROC_GET_IMPULSE_RESP_RSP	= 0x1200,
+	CONTROL_PROC_START_STREAMING		= 0x0013,
+	CONTROL_PROC_START_STREAMING_RSP	= 0x1300,
+	CONTROL_PROC_STOP_STREAMING		= 0x0014,
+	CONTROL_PROC_STOP_STREAMING_RSP		= 0x1400,
+	CONTROL_PROC_GET_DEMOD_STATS		= 0x0015,
+	CONTROL_PROC_GET_DEMOD_STATS_RSP	= 0x1500,
+	CONTROL_PROC_ELNA_CHANGE_MODE		= 0x0016,
+	CONTROL_PROC_ELNA_CHANGE_MODE_RSP	= 0x1600,
+	CONTROL_PROC_ODSP_CHANGE_MODE		= 0x0017,
+	CONTROL_PROC_ODSP_CHANGE_MODE_RSP	= 0x1700,
+	CONTROL_PROC_AGC_CHANGE_MODE		= 0x0018,
+	CONTROL_PROC_AGC_CHANGE_MODE_RSP	= 0x1800,
 
-   CONTROL_PROC_CONTEXT              = 0x00FC,
-   CONTROL_PROC_CONTEXT_RSP          = 0xFC00,
-   CONTROL_PROC_DUMP_MEMORY          = 0x00FD,
-   CONTROL_PROC_DUMP_MEMORY_RSP      = 0xFD00,
-   CONTROL_PROC_DUMPLOG_MEMORY       = 0x00FE,
-   CONTROL_PROC_DUMPLOG_MEMORY_RSP   = 0xFE00,
-   CONTROL_PROC_TURNOFF              = 0x00FF,
-   CONTROL_PROC_TURNOFF_RSP          = 0xFF00
-} control_proc;
+	CONTROL_PROC_CONTEXT			= 0x00FC,
+	CONTROL_PROC_CONTEXT_RSP		= 0xFC00,
+	CONTROL_PROC_DUMP_MEMORY		= 0x00FD,
+	CONTROL_PROC_DUMP_MEMORY_RSP		= 0xFD00,
+	CONTROL_PROC_DUMPLOG_MEMORY		= 0x00FE,
+	CONTROL_PROC_DUMPLOG_MEMORY_RSP		= 0xFE00,
+	CONTROL_PROC_TURNOFF			= 0x00FF,
+	CONTROL_PROC_TURNOFF_RSP		= 0xFF00
+};
 
+union as10x_turn_on {
+	/* request */
+	struct {
+		/* request identifier */
+		uint16_t proc_id;
+	} req;
+	/* response */
+	struct {
+		/* response identifier */
+		uint16_t proc_id;
+		/* error */
+		uint8_t error;
+	} rsp;
+} __packed;
 
-#pragma pack(1)
-typedef union {
-   /* request */
-   struct {
-      /* request identifier */
-      uint16_t proc_id;
-   } req;
-   /* response */
-   struct {
-      /* response identifier */
-      uint16_t proc_id;
-      /* error */
-      uint8_t error;
-   } rsp;
-} TURN_ON;
+union as10x_turn_off {
+	/* request */
+	struct {
+		/* request identifier */
+		uint16_t proc_id;
+	} req;
+	/* response */
+	struct {
+		/* response identifier */
+		uint16_t proc_id;
+		/* error */
+		uint8_t err;
+	} rsp;
+} __packed;
 
-typedef union {
-   /* request */
-   struct {
-      /* request identifier */
-      uint16_t proc_id;
-   } req;
-   /* response */
-   struct {
-      /* response identifier */
-      uint16_t proc_id;
-      /* error */
-      uint8_t err;
-   } rsp;
-} TURN_OFF;
+union as10x_set_tune {
+	/* request */
+	struct {
+		/* request identifier */
+		uint16_t proc_id;
+		/* tune params */
+		struct as10x_tune_args args;
+	} req;
+	/* response */
+	struct {
+		/* response identifier */
+		uint16_t proc_id;
+		/* response error */
+		uint8_t error;
+	} rsp;
+} __packed;
 
-typedef union {
-   /* request */
-   struct {
-      /* request identifier */
-      uint16_t proc_id;
-      /* tune params */
-      struct as10x_tune_args args;
-   } req;
-   /* response */
-   struct {
-      /* response identifier */
-      uint16_t proc_id;
-      /* response error */
-      uint8_t error;
-   } rsp;
-} SET_TUNE;
+union as10x_get_tune_status {
+	/* request */
+	struct {
+		/* request identifier */
+		uint16_t proc_id;
+	} req;
+	/* response */
+	struct {
+		/* response identifier */
+		uint16_t proc_id;
+		/* response error */
+		uint8_t error;
+		/* tune status */
+		struct as10x_tune_status sts;
+	} rsp;
+} __packed;
 
-typedef union {
-   /* request */
-   struct {
-      /* request identifier */
-      uint16_t proc_id;
-   } req;
-   /* response */
-   struct {
-      /* response identifier */
-      uint16_t proc_id;
-      /* response error */
-      uint8_t error;
-      /* tune status */
-      struct as10x_tune_status sts;
-   } rsp;
-} GET_TUNE_STATUS;
+union as10x_get_tps {
+	/* request */
+	struct {
+		/* request identifier */
+		uint16_t proc_id;
+	} req;
+	/* response */
+	struct {
+		/* response identifier */
+		uint16_t proc_id;
+		/* response error */
+		uint8_t error;
+		/* tps details */
+		struct as10x_tps tps;
+	} rsp;
+} __packed;
 
-typedef union {
-   /* request */
-   struct {
-      /* request identifier */
-      uint16_t proc_id;
-   } req;
-   /* response */
-   struct {
-      /* response identifier */
-      uint16_t proc_id;
-      /* response error */
-      uint8_t error;
-      /* tps details */
-      struct as10x_tps tps;
-   } rsp;
-} GET_TPS;
+union as10x_common {
+	/* request */
+	struct {
+		/* request identifier */
+		uint16_t  proc_id;
+	} req;
+	/* response */
+	struct {
+		/* response identifier */
+		uint16_t proc_id;
+		/* response error */
+		uint8_t error;
+	} rsp;
+} __packed;
 
-typedef union {
-   /* request */
-   struct {
-      /* request identifier */
-      uint16_t  proc_id;
-   } req;
-   /* response */
-   struct {
-      /* response identifier */
-      uint16_t proc_id;
-      /* response error */
-      uint8_t error;
-   } rsp;
-} COMMON;
+union as10x_add_pid_filter {
+	/* request */
+	struct {
+		/* request identifier */
+		uint16_t  proc_id;
+		/* PID to filter */
+		uint16_t  pid;
+		/* stream type (MPE, PSI/SI or PES )*/
+		uint8_t stream_type;
+		/* PID index in filter table */
+		uint8_t idx;
+	} req;
+	/* response */
+	struct {
+		/* response identifier */
+		uint16_t proc_id;
+		/* response error */
+		uint8_t error;
+		/* Filter id */
+		uint8_t filter_id;
+	} rsp;
+} __packed;
 
-typedef union {
-   /* request */
-   struct {
-      /* request identifier */
-      uint16_t  proc_id;
-      /* PID to filter */
-      uint16_t  pid;
-      /* stream type (MPE, PSI/SI or PES )*/
-      uint8_t stream_type;
-      /* PID index in filter table */
-      uint8_t idx;
-   } req;
-   /* response */
-   struct {
-      /* response identifier */
-      uint16_t proc_id;
-      /* response error */
-      uint8_t error;
-      /* Filter id */
-      uint8_t filter_id;
-   } rsp;
-} ADD_PID_FILTER;
+union as10x_del_pid_filter {
+	/* request */
+	struct {
+		/* request identifier */
+		uint16_t  proc_id;
+		/* PID to remove */
+		uint16_t  pid;
+	} req;
+	/* response */
+	struct {
+		/* response identifier */
+		uint16_t proc_id;
+		/* response error */
+		uint8_t error;
+	} rsp;
+} __packed;
 
-typedef union {
-   /* request */
-   struct {
-      /* request identifier */
-      uint16_t  proc_id;
-      /* PID to remove */
-      uint16_t  pid;
-   } req;
-   /* response */
-   struct {
-      /* response identifier */
-      uint16_t proc_id;
-      /* response error */
-      uint8_t error;
-   } rsp;
-} DEL_PID_FILTER;
+union as10x_start_streaming {
+	/* request */
+	struct {
+		/* request identifier */
+		uint16_t proc_id;
+	} req;
+	/* response */
+	struct {
+		/* response identifier */
+		uint16_t proc_id;
+		/* error */
+		uint8_t error;
+	} rsp;
+} __packed;
 
-typedef union {
-   /* request */
-   struct {
-      /* request identifier */
-      uint16_t proc_id;
-   } req;
-   /* response */
-   struct {
-      /* response identifier */
-      uint16_t proc_id;
-      /* error */
-      uint8_t error;
-   } rsp;
-} START_STREAMING;
+union as10x_stop_streaming {
+	/* request */
+	struct {
+		/* request identifier */
+		uint16_t proc_id;
+	} req;
+	/* response */
+	struct {
+		/* response identifier */
+		uint16_t proc_id;
+		/* error */
+		uint8_t error;
+	} rsp;
+} __packed;
 
-typedef union {
-   /* request */
-   struct {
-      /* request identifier */
-      uint16_t proc_id;
-   } req;
-   /* response */
-   struct {
-      /* response identifier */
-      uint16_t proc_id;
-      /* error */
-      uint8_t error;
-   } rsp;
-} STOP_STREAMING;
+union as10x_get_demod_stats {
+	/* request */
+	struct {
+		/* request identifier */
+		uint16_t proc_id;
+	} req;
+	/* response */
+	struct {
+		/* response identifier */
+		uint16_t proc_id;
+		/* error */
+		uint8_t error;
+		/* demod stats */
+		struct as10x_demod_stats stats;
+	} rsp;
+} __packed;
 
-typedef union {
-   /* request */
-   struct {
-      /* request identifier */
-      uint16_t proc_id;
-   } req;
-   /* response */
-   struct {
-      /* response identifier */
-      uint16_t proc_id;
-      /* error */
-      uint8_t error;
-      /* demod stats */
-      struct as10x_demod_stats stats;
-   } rsp;
-} GET_DEMOD_STATS;
+union as10x_get_impulse_resp {
+	/* request */
+	struct {
+		/* request identifier */
+		uint16_t proc_id;
+	} req;
+	/* response */
+	struct {
+		/* response identifier */
+		uint16_t proc_id;
+		/* error */
+		uint8_t error;
+		/* impulse response ready */
+		uint8_t is_ready;
+	} rsp;
+} __packed;
 
-typedef union {
-   /* request */
-   struct {
-      /* request identifier */
-      uint16_t proc_id;
-   } req;
-   /* response */
-   struct {
-      /* response identifier */
-      uint16_t proc_id;
-      /* error */
-      uint8_t error;
-      /* impulse response ready */
-      uint8_t is_ready;
-   } rsp;
-} GET_IMPULSE_RESP;
+union as10x_fw_context {
+	/* request */
+	struct {
+		/* request identifier */
+		uint16_t proc_id;
+		/* value to write (for set context)*/
+		struct as10x_register_value reg_val;
+		/* context tag */
+		uint16_t tag;
+		/* context request type */
+		uint16_t type;
+	} req;
+	/* response */
+	struct {
+		/* response identifier */
+		uint16_t proc_id;
+		/* value read (for get context) */
+		struct as10x_register_value reg_val;
+		/* context request type */
+		uint16_t type;
+		/* error */
+		uint8_t error;
+	} rsp;
+} __packed;
 
-typedef union {
-   /* request */
-   struct {
-      /* request identifier */
-      uint16_t proc_id;
-      /* value to write (for set context)*/
-      struct as10x_register_value reg_val;
-      /* context tag */
-      uint16_t tag;
-      /* context request type */
-      uint16_t type;
-   } req;
-   /* response */
-   struct {
-      /* response identifier */
-      uint16_t proc_id;
-      /* value read (for get context) */
-      struct as10x_register_value reg_val;
-      /* context request type */
-      uint16_t type;
-      /* error */
-      uint8_t error;
-   } rsp;
-} FW_CONTEXT;
+union as10x_set_register {
+	/* request */
+	struct {
+		/* response identifier */
+		uint16_t proc_id;
+		/* register description */
+		struct as10x_register_addr reg_addr;
+		/* register content */
+		struct as10x_register_value reg_val;
+	} req;
+	/* response */
+	struct {
+		/* response identifier */
+		uint16_t proc_id;
+		/* error */
+		uint8_t error;
+	} rsp;
+} __packed;
 
-typedef union {
-   /* request */
-   struct {
-      /* response identifier */
-      uint16_t proc_id;
-      /* register description */
-      struct as10x_register_addr reg_addr;
-      /* register content */
-      struct as10x_register_value reg_val;
-   } req;
-   /* response */
-   struct {
-      /* response identifier */
-      uint16_t proc_id;
-      /* error */
-      uint8_t error;
-   } rsp;
-} SET_REGISTER;
+union as10x_get_register {
+	/* request */
+	struct {
+		/* response identifier */
+		uint16_t proc_id;
+		/* register description */
+		struct as10x_register_addr reg_addr;
+	} req;
+	/* response */
+	struct {
+		/* response identifier */
+		uint16_t proc_id;
+		/* error */
+		uint8_t error;
+		/* register content */
+		struct as10x_register_value reg_val;
+	} rsp;
+} __packed;
 
-typedef union {
-   /* request */
-   struct {
-      /* response identifier */
-      uint16_t proc_id;
-      /* register description */
-      struct as10x_register_addr reg_addr;
-   } req;
-   /* response */
-   struct {
-      /* response identifier */
-      uint16_t proc_id;
-      /* error */
-      uint8_t error;
-      /* register content */
-      struct as10x_register_value reg_val;
-   } rsp;
-} GET_REGISTER;
-
-typedef union {
-   /* request */
-   struct {
-      /* request identifier */
-      uint16_t proc_id;
-      /* mode */
-      uint8_t mode;
-   } req;
-   /* response */
-   struct {
-      /* response identifier */
-      uint16_t proc_id;
-      /* error */
-      uint8_t error;
-   } rsp;
-} CFG_CHANGE_MODE;
+union as10x_cfg_change_mode {
+	/* request */
+	struct {
+		/* request identifier */
+		uint16_t proc_id;
+		/* mode */
+		uint8_t mode;
+	} req;
+	/* response */
+	struct {
+		/* response identifier */
+		uint16_t proc_id;
+		/* error */
+		uint8_t error;
+	} rsp;
+} __packed;
 
 struct as10x_cmd_header_t {
-   uint16_t req_id;
-   uint16_t prog;
-   uint16_t version;
-   uint16_t data_len;
-};
+	uint16_t req_id;
+	uint16_t prog;
+	uint16_t version;
+	uint16_t data_len;
+} __packed;
 
 #define DUMP_BLOCK_SIZE 16
-typedef union {
-   /* request */
-   struct {
-      /* request identifier */
-      uint16_t proc_id;
-      /* dump memory type request */
-      uint8_t dump_req;
-      /* register description */
-      struct as10x_register_addr reg_addr;
-      /* nb blocks to read */
-      uint16_t num_blocks;
-   } req;
-   /* response */
-   struct {
-      /* response identifier */
-      uint16_t proc_id;
-      /* error */
-      uint8_t error;
-      /* dump response */
-      uint8_t dump_rsp;
-      /* data */
-      union {
-	 uint8_t  data8[DUMP_BLOCK_SIZE];
-	 uint16_t data16[DUMP_BLOCK_SIZE / sizeof(uint16_t)];
-	 uint32_t data32[DUMP_BLOCK_SIZE / sizeof(uint32_t)];
-      } u;
-   } rsp;
-} DUMP_MEMORY;
 
-typedef union {
-   struct {
-      /* request identifier */
-      uint16_t proc_id;
-      /* dump memory type request */
-      uint8_t dump_req;
-   } req;
-   struct {
-      /* request identifier */
-      uint16_t proc_id;
-      /* error */
-      uint8_t error;
-      /* dump response */
-      uint8_t dump_rsp;
-      /* dump data */
-      uint8_t data[DUMP_BLOCK_SIZE];
-   } rsp;
-} DUMPLOG_MEMORY;
+union as10x_dump_memory {
+	/* request */
+	struct {
+		/* request identifier */
+		uint16_t proc_id;
+		/* dump memory type request */
+		uint8_t dump_req;
+		/* register description */
+		struct as10x_register_addr reg_addr;
+		/* nb blocks to read */
+		uint16_t num_blocks;
+	} req;
+	/* response */
+	struct {
+		/* response identifier */
+		uint16_t proc_id;
+		/* error */
+		uint8_t error;
+		/* dump response */
+		uint8_t dump_rsp;
+		/* data */
+		union {
+			uint8_t  data8[DUMP_BLOCK_SIZE];
+			uint16_t data16[DUMP_BLOCK_SIZE / sizeof(uint16_t)];
+			uint32_t data32[DUMP_BLOCK_SIZE / sizeof(uint32_t)];
+		} u;
+	} rsp;
+} __packed;
 
-typedef union {
-   /* request */
-   struct {
-      uint16_t proc_id;
-      uint8_t data[64 - sizeof(struct as10x_cmd_header_t) -2 /* proc_id */];
-   } req;
-   /* response */
-   struct {
-      uint16_t proc_id;
-      uint8_t error;
-      uint8_t data[64 - sizeof(struct as10x_cmd_header_t) /* header */
-		      - 2 /* proc_id */ - 1 /* rc */];
-   } rsp;
-} RAW_DATA;
+union as10x_dumplog_memory {
+	struct {
+		/* request identifier */
+		uint16_t proc_id;
+		/* dump memory type request */
+		uint8_t dump_req;
+	} req;
+	struct {
+		/* request identifier */
+		uint16_t proc_id;
+		/* error */
+		uint8_t error;
+		/* dump response */
+		uint8_t dump_rsp;
+		/* dump data */
+		uint8_t data[DUMP_BLOCK_SIZE];
+	} rsp;
+} __packed;
+
+union as10x_raw_data {
+	/* request */
+	struct {
+		uint16_t proc_id;
+		uint8_t data[64 - sizeof(struct as10x_cmd_header_t)
+			     - 2 /* proc_id */];
+	} req;
+	/* response */
+	struct {
+		uint16_t proc_id;
+		uint8_t error;
+		uint8_t data[64 - sizeof(struct as10x_cmd_header_t)
+			     - 2 /* proc_id */ - 1 /* rc */];
+	} rsp;
+} __packed;
 
 struct as10x_cmd_t {
-   /* header */
-   struct as10x_cmd_header_t header;
-   /* body */
-   union {
-      TURN_ON           turn_on;
-      TURN_OFF          turn_off;
-      SET_TUNE          set_tune;
-      GET_TUNE_STATUS   get_tune_status;
-      GET_TPS           get_tps;
-      COMMON            common;
-      ADD_PID_FILTER    add_pid_filter;
-      DEL_PID_FILTER    del_pid_filter;
-      START_STREAMING   start_streaming;
-      STOP_STREAMING    stop_streaming;
-      GET_DEMOD_STATS   get_demod_stats;
-      GET_IMPULSE_RESP  get_impulse_rsp;
-      FW_CONTEXT        context;
-      SET_REGISTER      set_register;
-      GET_REGISTER      get_register;
-      CFG_CHANGE_MODE   cfg_change_mode;
-      DUMP_MEMORY       dump_memory;
-      DUMPLOG_MEMORY    dumplog_memory;
-      RAW_DATA          raw_data;
-   } body;
-};
+	struct as10x_cmd_header_t header;
+	union {
+		union as10x_turn_on		turn_on;
+		union as10x_turn_off		turn_off;
+		union as10x_set_tune		set_tune;
+		union as10x_get_tune_status	get_tune_status;
+		union as10x_get_tps		get_tps;
+		union as10x_common		common;
+		union as10x_add_pid_filter	add_pid_filter;
+		union as10x_del_pid_filter	del_pid_filter;
+		union as10x_start_streaming	start_streaming;
+		union as10x_stop_streaming	stop_streaming;
+		union as10x_get_demod_stats	get_demod_stats;
+		union as10x_get_impulse_resp	get_impulse_rsp;
+		union as10x_fw_context		context;
+		union as10x_set_register	set_register;
+		union as10x_get_register	get_register;
+		union as10x_cfg_change_mode	cfg_change_mode;
+		union as10x_dump_memory		dump_memory;
+		union as10x_dumplog_memory	dumplog_memory;
+		union as10x_raw_data		raw_data;
+	} body;
+} __packed;
 
 struct as10x_token_cmd_t {
-   /* token cmd */
-   struct as10x_cmd_t c;
-   /* token response */
-   struct as10x_cmd_t r;
-};
-#pragma pack()
+	/* token cmd */
+	struct as10x_cmd_t c;
+	/* token response */
+	struct as10x_cmd_t r;
+} __packed;
 
 
 /**************************/
@@ -491,50 +488,42 @@
 		      uint16_t cmd_len);
 int as10x_rsp_parse(struct as10x_cmd_t *r, uint16_t proc_id);
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /* as10x cmd */
-int as10x_cmd_turn_on(as10x_handle_t *phandle);
-int as10x_cmd_turn_off(as10x_handle_t *phandle);
+int as10x_cmd_turn_on(struct as10x_bus_adapter_t *adap);
+int as10x_cmd_turn_off(struct as10x_bus_adapter_t *adap);
 
-int as10x_cmd_set_tune(as10x_handle_t *phandle,
+int as10x_cmd_set_tune(struct as10x_bus_adapter_t *adap,
 		       struct as10x_tune_args *ptune);
 
-int as10x_cmd_get_tune_status(as10x_handle_t *phandle,
+int as10x_cmd_get_tune_status(struct as10x_bus_adapter_t *adap,
 			      struct as10x_tune_status *pstatus);
 
-int as10x_cmd_get_tps(as10x_handle_t *phandle,
+int as10x_cmd_get_tps(struct as10x_bus_adapter_t *adap,
 		      struct as10x_tps *ptps);
 
-int as10x_cmd_get_demod_stats(as10x_handle_t  *phandle,
+int as10x_cmd_get_demod_stats(struct as10x_bus_adapter_t  *adap,
 			      struct as10x_demod_stats *pdemod_stats);
 
-int as10x_cmd_get_impulse_resp(as10x_handle_t *phandle,
+int as10x_cmd_get_impulse_resp(struct as10x_bus_adapter_t *adap,
 			       uint8_t *is_ready);
 
 /* as10x cmd stream */
-int as10x_cmd_add_PID_filter(as10x_handle_t *phandle,
+int as10x_cmd_add_PID_filter(struct as10x_bus_adapter_t *adap,
 			     struct as10x_ts_filter *filter);
-int as10x_cmd_del_PID_filter(as10x_handle_t *phandle,
+int as10x_cmd_del_PID_filter(struct as10x_bus_adapter_t *adap,
 			     uint16_t pid_value);
 
-int as10x_cmd_start_streaming(as10x_handle_t *phandle);
-int as10x_cmd_stop_streaming(as10x_handle_t *phandle);
+int as10x_cmd_start_streaming(struct as10x_bus_adapter_t *adap);
+int as10x_cmd_stop_streaming(struct as10x_bus_adapter_t *adap);
 
 /* as10x cmd cfg */
-int as10x_cmd_set_context(as10x_handle_t *phandle,
+int as10x_cmd_set_context(struct as10x_bus_adapter_t *adap,
 			  uint16_t tag,
 			  uint32_t value);
-int as10x_cmd_get_context(as10x_handle_t *phandle,
+int as10x_cmd_get_context(struct as10x_bus_adapter_t *adap,
 			  uint16_t tag,
 			  uint32_t *pvalue);
 
-int as10x_cmd_eLNA_change_mode(as10x_handle_t *phandle, uint8_t mode);
+int as10x_cmd_eLNA_change_mode(struct as10x_bus_adapter_t *adap, uint8_t mode);
 int as10x_context_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id);
-#ifdef __cplusplus
-}
 #endif
-#endif
-/* EOF - vim: set textwidth=80 ts=3 sw=3 sts=3 et: */
diff --git a/drivers/staging/media/as102/as10x_cmd_cfg.c b/drivers/staging/media/as102/as10x_cmd_cfg.c
index ec6f69f..d2a4bce 100644
--- a/drivers/staging/media/as102/as10x_cmd_cfg.c
+++ b/drivers/staging/media/as102/as10x_cmd_cfg.c
@@ -28,13 +28,13 @@
 
 /**
  * as10x_cmd_get_context - Send get context command to AS10x
- * @phandle:   pointer to AS10x handle
+ * @adap:      pointer to AS10x bus adapter
  * @tag:       context tag
  * @pvalue:    pointer where to store context value read
  *
  * Return 0 on success or negative value in case of error.
  */
-int as10x_cmd_get_context(as10x_handle_t *phandle, uint16_t tag,
+int as10x_cmd_get_context(struct as10x_bus_adapter_t *adap, uint16_t tag,
 			  uint32_t *pvalue)
 {
 	int  error;
@@ -42,11 +42,11 @@
 
 	ENTER();
 
-	pcmd = phandle->cmd;
-	prsp = phandle->rsp;
+	pcmd = adap->cmd;
+	prsp = adap->rsp;
 
 	/* prepare command */
-	as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+	as10x_cmd_build(pcmd, (++adap->cmd_xid),
 			sizeof(pcmd->body.context.req));
 
 	/* fill command */
@@ -55,14 +55,14 @@
 	pcmd->body.context.req.type = cpu_to_le16(GET_CONTEXT_DATA);
 
 	/* send command */
-	if (phandle->ops->xfer_cmd) {
-		error  = phandle->ops->xfer_cmd(phandle,
-						(uint8_t *) pcmd,
-						sizeof(pcmd->body.context.req)
-						+ HEADER_SIZE,
-						(uint8_t *) prsp,
-						sizeof(prsp->body.context.rsp)
-						+ HEADER_SIZE);
+	if (adap->ops->xfer_cmd) {
+		error  = adap->ops->xfer_cmd(adap,
+					     (uint8_t *) pcmd,
+					     sizeof(pcmd->body.context.req)
+					     + HEADER_SIZE,
+					     (uint8_t *) prsp,
+					     sizeof(prsp->body.context.rsp)
+					     + HEADER_SIZE);
 	} else {
 		error = AS10X_CMD_ERROR;
 	}
@@ -87,13 +87,13 @@
 
 /**
  * as10x_cmd_set_context - send set context command to AS10x
- * @phandle:   pointer to AS10x handle
+ * @adap:      pointer to AS10x bus adapter
  * @tag:       context tag
  * @value:     value to set in context
  *
  * Return 0 on success or negative value in case of error.
  */
-int as10x_cmd_set_context(as10x_handle_t *phandle, uint16_t tag,
+int as10x_cmd_set_context(struct as10x_bus_adapter_t *adap, uint16_t tag,
 			  uint32_t value)
 {
 	int error;
@@ -101,11 +101,11 @@
 
 	ENTER();
 
-	pcmd = phandle->cmd;
-	prsp = phandle->rsp;
+	pcmd = adap->cmd;
+	prsp = adap->rsp;
 
 	/* prepare command */
-	as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+	as10x_cmd_build(pcmd, (++adap->cmd_xid),
 			sizeof(pcmd->body.context.req));
 
 	/* fill command */
@@ -116,14 +116,14 @@
 	pcmd->body.context.req.type = cpu_to_le16(SET_CONTEXT_DATA);
 
 	/* send command */
-	if (phandle->ops->xfer_cmd) {
-		error  = phandle->ops->xfer_cmd(phandle,
-						(uint8_t *) pcmd,
-						sizeof(pcmd->body.context.req)
-						+ HEADER_SIZE,
-						(uint8_t *) prsp,
-						sizeof(prsp->body.context.rsp)
-						+ HEADER_SIZE);
+	if (adap->ops->xfer_cmd) {
+		error  = adap->ops->xfer_cmd(adap,
+					     (uint8_t *) pcmd,
+					     sizeof(pcmd->body.context.req)
+					     + HEADER_SIZE,
+					     (uint8_t *) prsp,
+					     sizeof(prsp->body.context.rsp)
+					     + HEADER_SIZE);
 	} else {
 		error = AS10X_CMD_ERROR;
 	}
@@ -142,7 +142,7 @@
 
 /**
  * as10x_cmd_eLNA_change_mode - send eLNA change mode command to AS10x
- * @phandle:   pointer to AS10x handle
+ * @adap:      pointer to AS10x bus adapter
  * @mode:      mode selected:
  *	        - ON    : 0x0 => eLNA always ON
  *	        - OFF   : 0x1 => eLNA always OFF
@@ -151,18 +151,18 @@
  *
  * Return 0 on success or negative value in case of error.
  */
-int as10x_cmd_eLNA_change_mode(as10x_handle_t *phandle, uint8_t mode)
+int as10x_cmd_eLNA_change_mode(struct as10x_bus_adapter_t *adap, uint8_t mode)
 {
 	int error;
 	struct as10x_cmd_t *pcmd, *prsp;
 
 	ENTER();
 
-	pcmd = phandle->cmd;
-	prsp = phandle->rsp;
+	pcmd = adap->cmd;
+	prsp = adap->rsp;
 
 	/* prepare command */
-	as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+	as10x_cmd_build(pcmd, (++adap->cmd_xid),
 			sizeof(pcmd->body.cfg_change_mode.req));
 
 	/* fill command */
@@ -171,8 +171,8 @@
 	pcmd->body.cfg_change_mode.req.mode = mode;
 
 	/* send command */
-	if (phandle->ops->xfer_cmd) {
-		error  = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
+	if (adap->ops->xfer_cmd) {
+		error  = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
 				sizeof(pcmd->body.cfg_change_mode.req)
 				+ HEADER_SIZE, (uint8_t *) prsp,
 				sizeof(prsp->body.cfg_change_mode.rsp)
diff --git a/drivers/staging/media/as102/as10x_cmd_stream.c b/drivers/staging/media/as102/as10x_cmd_stream.c
index 045c706..6d000f6 100644
--- a/drivers/staging/media/as102/as10x_cmd_stream.c
+++ b/drivers/staging/media/as102/as10x_cmd_stream.c
@@ -23,12 +23,12 @@
 
 /**
  * as10x_cmd_add_PID_filter - send add filter command to AS10x
- * @phandle:   pointer to AS10x handle
+ * @adap:      pointer to AS10x bus adapter
  * @filter:    TSFilter filter for DVB-T
  *
  * Return 0 on success or negative value in case of error.
  */
-int as10x_cmd_add_PID_filter(as10x_handle_t *phandle,
+int as10x_cmd_add_PID_filter(struct as10x_bus_adapter_t *adap,
 			     struct as10x_ts_filter *filter)
 {
 	int error;
@@ -36,11 +36,11 @@
 
 	ENTER();
 
-	pcmd = phandle->cmd;
-	prsp = phandle->rsp;
+	pcmd = adap->cmd;
+	prsp = adap->rsp;
 
 	/* prepare command */
-	as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+	as10x_cmd_build(pcmd, (++adap->cmd_xid),
 			sizeof(pcmd->body.add_pid_filter.req));
 
 	/* fill command */
@@ -55,8 +55,8 @@
 		pcmd->body.add_pid_filter.req.idx = 0xFF;
 
 	/* send command */
-	if (phandle->ops->xfer_cmd) {
-		error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
+	if (adap->ops->xfer_cmd) {
+		error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
 				sizeof(pcmd->body.add_pid_filter.req)
 				+ HEADER_SIZE, (uint8_t *) prsp,
 				sizeof(prsp->body.add_pid_filter.rsp)
@@ -83,12 +83,12 @@
 
 /**
  * as10x_cmd_del_PID_filter - Send delete filter command to AS10x
- * @phandle:      pointer to AS10x handle
+ * @adap:         pointer to AS10x bus adapte
  * @pid_value:    PID to delete
  *
  * Return 0 on success or negative value in case of error.
  */
-int as10x_cmd_del_PID_filter(as10x_handle_t *phandle,
+int as10x_cmd_del_PID_filter(struct as10x_bus_adapter_t *adap,
 			     uint16_t pid_value)
 {
 	int error;
@@ -96,11 +96,11 @@
 
 	ENTER();
 
-	pcmd = phandle->cmd;
-	prsp = phandle->rsp;
+	pcmd = adap->cmd;
+	prsp = adap->rsp;
 
 	/* prepare command */
-	as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+	as10x_cmd_build(pcmd, (++adap->cmd_xid),
 			sizeof(pcmd->body.del_pid_filter.req));
 
 	/* fill command */
@@ -109,8 +109,8 @@
 	pcmd->body.del_pid_filter.req.pid = cpu_to_le16(pid_value);
 
 	/* send command */
-	if (phandle->ops->xfer_cmd) {
-		error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
+	if (adap->ops->xfer_cmd) {
+		error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
 				sizeof(pcmd->body.del_pid_filter.req)
 				+ HEADER_SIZE, (uint8_t *) prsp,
 				sizeof(prsp->body.del_pid_filter.rsp)
@@ -132,22 +132,22 @@
 
 /**
  * as10x_cmd_start_streaming - Send start streaming command to AS10x
- * @phandle:   pointer to AS10x handle
+ * @adap:   pointer to AS10x bus adapter
  *
  * Return 0 on success or negative value in case of error.
  */
-int as10x_cmd_start_streaming(as10x_handle_t *phandle)
+int as10x_cmd_start_streaming(struct as10x_bus_adapter_t *adap)
 {
 	int error;
 	struct as10x_cmd_t *pcmd, *prsp;
 
 	ENTER();
 
-	pcmd = phandle->cmd;
-	prsp = phandle->rsp;
+	pcmd = adap->cmd;
+	prsp = adap->rsp;
 
 	/* prepare command */
-	as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+	as10x_cmd_build(pcmd, (++adap->cmd_xid),
 			sizeof(pcmd->body.start_streaming.req));
 
 	/* fill command */
@@ -155,8 +155,8 @@
 		cpu_to_le16(CONTROL_PROC_START_STREAMING);
 
 	/* send command */
-	if (phandle->ops->xfer_cmd) {
-		error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
+	if (adap->ops->xfer_cmd) {
+		error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
 				sizeof(pcmd->body.start_streaming.req)
 				+ HEADER_SIZE, (uint8_t *) prsp,
 				sizeof(prsp->body.start_streaming.rsp)
@@ -178,22 +178,22 @@
 
 /**
  * as10x_cmd_stop_streaming - Send stop streaming command to AS10x
- * @phandle:   pointer to AS10x handle
+ * @adap:   pointer to AS10x bus adapter
  *
  * Return 0 on success or negative value in case of error.
  */
-int as10x_cmd_stop_streaming(as10x_handle_t *phandle)
+int as10x_cmd_stop_streaming(struct as10x_bus_adapter_t *adap)
 {
 	int8_t error;
 	struct as10x_cmd_t *pcmd, *prsp;
 
 	ENTER();
 
-	pcmd = phandle->cmd;
-	prsp = phandle->rsp;
+	pcmd = adap->cmd;
+	prsp = adap->rsp;
 
 	/* prepare command */
-	as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+	as10x_cmd_build(pcmd, (++adap->cmd_xid),
 			sizeof(pcmd->body.stop_streaming.req));
 
 	/* fill command */
@@ -201,8 +201,8 @@
 		cpu_to_le16(CONTROL_PROC_STOP_STREAMING);
 
 	/* send command */
-	if (phandle->ops->xfer_cmd) {
-		error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
+	if (adap->ops->xfer_cmd) {
+		error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
 				sizeof(pcmd->body.stop_streaming.req)
 				+ HEADER_SIZE, (uint8_t *) prsp,
 				sizeof(prsp->body.stop_streaming.rsp)
diff --git a/drivers/staging/media/as102/as10x_handle.h b/drivers/staging/media/as102/as10x_handle.h
index 4f01a76..62b9795 100644
--- a/drivers/staging/media/as102/as10x_handle.h
+++ b/drivers/staging/media/as102/as10x_handle.h
@@ -17,41 +17,37 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #ifdef __KERNEL__
-struct as102_bus_adapter_t;
+struct as10x_bus_adapter_t;
 struct as102_dev_t;
 
-#define as10x_handle_t struct as102_bus_adapter_t
 #include "as10x_cmd.h"
 
 /* values for "mode" field */
-#define REGMODE8         8
-#define REGMODE16        16
-#define REGMODE32        32
+#define REGMODE8	8
+#define REGMODE16	16
+#define REGMODE32	32
 
 struct as102_priv_ops_t {
-	int (*upload_fw_pkt) (struct as102_bus_adapter_t *bus_adap,
+	int (*upload_fw_pkt) (struct as10x_bus_adapter_t *bus_adap,
 			      unsigned char *buf, int buflen, int swap32);
 
-	int (*send_cmd) (struct as102_bus_adapter_t *bus_adap,
+	int (*send_cmd) (struct as10x_bus_adapter_t *bus_adap,
 			 unsigned char *buf, int buflen);
 
-	int (*xfer_cmd) (struct as102_bus_adapter_t *bus_adap,
+	int (*xfer_cmd) (struct as10x_bus_adapter_t *bus_adap,
 			 unsigned char *send_buf, int send_buf_len,
 			 unsigned char *recv_buf, int recv_buf_len);
-/*
-	int (*pid_filter) (struct as102_bus_adapter_t *bus_adap,
-			   int index, u16 pid, int onoff);
-*/
+
 	int (*start_stream) (struct as102_dev_t *dev);
 	void (*stop_stream) (struct as102_dev_t *dev);
 
-	int (*reset_target) (struct as102_bus_adapter_t *bus_adap);
+	int (*reset_target) (struct as10x_bus_adapter_t *bus_adap);
 
-	int (*read_write)(struct as102_bus_adapter_t *bus_adap, uint8_t mode,
+	int (*read_write)(struct as10x_bus_adapter_t *bus_adap, uint8_t mode,
 			  uint32_t rd_addr, uint16_t rd_len,
 			  uint32_t wr_addr, uint16_t wr_len);
 
-	int (*as102_read_ep2) (struct as102_bus_adapter_t *bus_adap,
+	int (*as102_read_ep2) (struct as10x_bus_adapter_t *bus_adap,
 			       unsigned char *recv_buf,
 			       int recv_buf_len);
 };
diff --git a/drivers/staging/media/as102/as10x_types.h b/drivers/staging/media/as102/as10x_types.h
index 3dedb3c..c40c812 100644
--- a/drivers/staging/media/as102/as10x_types.h
+++ b/drivers/staging/media/as102/as10x_types.h
@@ -26,173 +26,169 @@
 /*********************************/
 
 /* bandwidth constant values */
-#define BW_5_MHZ           0x00
-#define BW_6_MHZ           0x01
-#define BW_7_MHZ           0x02
-#define BW_8_MHZ           0x03
+#define BW_5_MHZ		0x00
+#define BW_6_MHZ		0x01
+#define BW_7_MHZ		0x02
+#define BW_8_MHZ		0x03
 
 /* hierarchy priority selection values */
-#define HIER_NO_PRIORITY   0x00
-#define HIER_LOW_PRIORITY  0x01
-#define HIER_HIGH_PRIORITY 0x02
+#define HIER_NO_PRIORITY	0x00
+#define HIER_LOW_PRIORITY	0x01
+#define HIER_HIGH_PRIORITY	0x02
 
 /* constellation available values */
-#define CONST_QPSK         0x00
-#define CONST_QAM16        0x01
-#define CONST_QAM64        0x02
-#define CONST_UNKNOWN      0xFF
+#define CONST_QPSK		0x00
+#define CONST_QAM16		0x01
+#define CONST_QAM64		0x02
+#define CONST_UNKNOWN		0xFF
 
 /* hierarchy available values */
-#define HIER_NONE         0x00
-#define HIER_ALPHA_1      0x01
-#define HIER_ALPHA_2      0x02
-#define HIER_ALPHA_4      0x03
-#define HIER_UNKNOWN      0xFF
+#define HIER_NONE		0x00
+#define HIER_ALPHA_1		0x01
+#define HIER_ALPHA_2		0x02
+#define HIER_ALPHA_4		0x03
+#define HIER_UNKNOWN		0xFF
 
 /* interleaving available values */
-#define INTLV_NATIVE      0x00
-#define INTLV_IN_DEPTH    0x01
-#define INTLV_UNKNOWN     0xFF
+#define INTLV_NATIVE		0x00
+#define INTLV_IN_DEPTH		0x01
+#define INTLV_UNKNOWN		0xFF
 
 /* code rate available values */
-#define CODE_RATE_1_2     0x00
-#define CODE_RATE_2_3     0x01
-#define CODE_RATE_3_4     0x02
-#define CODE_RATE_5_6     0x03
-#define CODE_RATE_7_8     0x04
-#define CODE_RATE_UNKNOWN 0xFF
+#define CODE_RATE_1_2		0x00
+#define CODE_RATE_2_3		0x01
+#define CODE_RATE_3_4		0x02
+#define CODE_RATE_5_6		0x03
+#define CODE_RATE_7_8		0x04
+#define CODE_RATE_UNKNOWN	0xFF
 
 /* guard interval available values */
-#define GUARD_INT_1_32    0x00
-#define GUARD_INT_1_16    0x01
-#define GUARD_INT_1_8     0x02
-#define GUARD_INT_1_4     0x03
-#define GUARD_UNKNOWN     0xFF
+#define GUARD_INT_1_32		0x00
+#define GUARD_INT_1_16		0x01
+#define GUARD_INT_1_8		0x02
+#define GUARD_INT_1_4		0x03
+#define GUARD_UNKNOWN		0xFF
 
 /* transmission mode available values */
-#define TRANS_MODE_2K      0x00
-#define TRANS_MODE_8K      0x01
-#define TRANS_MODE_4K      0x02
-#define TRANS_MODE_UNKNOWN 0xFF
+#define TRANS_MODE_2K		0x00
+#define TRANS_MODE_8K		0x01
+#define TRANS_MODE_4K		0x02
+#define TRANS_MODE_UNKNOWN	0xFF
 
 /* DVBH signalling available values */
-#define TIMESLICING_PRESENT   0x01
-#define MPE_FEC_PRESENT       0x02
+#define TIMESLICING_PRESENT	0x01
+#define MPE_FEC_PRESENT		0x02
 
 /* tune state available */
-#define TUNE_STATUS_NOT_TUNED       0x00
-#define TUNE_STATUS_IDLE            0x01
-#define TUNE_STATUS_LOCKING         0x02
-#define TUNE_STATUS_SIGNAL_DVB_OK   0x03
-#define TUNE_STATUS_STREAM_DETECTED 0x04
-#define TUNE_STATUS_STREAM_TUNED    0x05
-#define TUNE_STATUS_ERROR           0xFF
+#define TUNE_STATUS_NOT_TUNED		0x00
+#define TUNE_STATUS_IDLE		0x01
+#define TUNE_STATUS_LOCKING		0x02
+#define TUNE_STATUS_SIGNAL_DVB_OK	0x03
+#define TUNE_STATUS_STREAM_DETECTED	0x04
+#define TUNE_STATUS_STREAM_TUNED	0x05
+#define TUNE_STATUS_ERROR		0xFF
 
 /* available TS FID filter types */
-#define TS_PID_TYPE_TS       0
-#define TS_PID_TYPE_PSI_SI   1
-#define TS_PID_TYPE_MPE      2
+#define TS_PID_TYPE_TS		0
+#define TS_PID_TYPE_PSI_SI	1
+#define TS_PID_TYPE_MPE		2
 
 /* number of echos available */
-#define MAX_ECHOS   15
+#define MAX_ECHOS	15
 
 /* Context types */
-#define CONTEXT_LNA                   1010
-#define CONTEXT_ELNA_HYSTERESIS       4003
-#define CONTEXT_ELNA_GAIN             4004
-#define CONTEXT_MER_THRESHOLD         5005
-#define CONTEXT_MER_OFFSET            5006
-#define CONTEXT_IR_STATE              7000
-#define CONTEXT_TSOUT_MSB_FIRST       7004
-#define CONTEXT_TSOUT_FALLING_EDGE    7005
+#define CONTEXT_LNA			1010
+#define CONTEXT_ELNA_HYSTERESIS		4003
+#define CONTEXT_ELNA_GAIN		4004
+#define CONTEXT_MER_THRESHOLD		5005
+#define CONTEXT_MER_OFFSET		5006
+#define CONTEXT_IR_STATE		7000
+#define CONTEXT_TSOUT_MSB_FIRST		7004
+#define CONTEXT_TSOUT_FALLING_EDGE	7005
 
 /* Configuration modes */
-#define CFG_MODE_ON     0
-#define CFG_MODE_OFF    1
-#define CFG_MODE_AUTO   2
+#define CFG_MODE_ON	0
+#define CFG_MODE_OFF	1
+#define CFG_MODE_AUTO	2
 
-#pragma pack(1)
 struct as10x_tps {
-   uint8_t constellation;
-   uint8_t hierarchy;
-   uint8_t interleaving_mode;
-   uint8_t code_rate_HP;
-   uint8_t code_rate_LP;
-   uint8_t guard_interval;
-   uint8_t transmission_mode;
-   uint8_t DVBH_mask_HP;
-   uint8_t DVBH_mask_LP;
-   uint16_t cell_ID;
-};
+	uint8_t constellation;
+	uint8_t hierarchy;
+	uint8_t interleaving_mode;
+	uint8_t code_rate_HP;
+	uint8_t code_rate_LP;
+	uint8_t guard_interval;
+	uint8_t transmission_mode;
+	uint8_t DVBH_mask_HP;
+	uint8_t DVBH_mask_LP;
+	uint16_t cell_ID;
+} __packed;
 
 struct as10x_tune_args {
-   /* frequency */
-   uint32_t freq;
-   /* bandwidth */
-   uint8_t bandwidth;
-   /* hierarchy selection */
-   uint8_t hier_select;
-   /* constellation */
-   uint8_t constellation;
-   /* hierarchy */
-   uint8_t hierarchy;
-   /* interleaving mode */
-   uint8_t interleaving_mode;
-   /* code rate */
-   uint8_t code_rate;
-   /* guard interval */
-   uint8_t guard_interval;
-   /* transmission mode */
-   uint8_t transmission_mode;
-};
+	/* frequency */
+	uint32_t freq;
+	/* bandwidth */
+	uint8_t bandwidth;
+	/* hierarchy selection */
+	uint8_t hier_select;
+	/* constellation */
+	uint8_t constellation;
+	/* hierarchy */
+	uint8_t hierarchy;
+	/* interleaving mode */
+	uint8_t interleaving_mode;
+	/* code rate */
+	uint8_t code_rate;
+	/* guard interval */
+	uint8_t guard_interval;
+	/* transmission mode */
+	uint8_t transmission_mode;
+} __packed;
 
 struct as10x_tune_status {
-   /* tune status */
-   uint8_t tune_state;
-   /* signal strength */
-   int16_t signal_strength;
-   /* packet error rate 10^-4 */
-   uint16_t PER;
-   /* bit error rate 10^-4 */
-   uint16_t BER;
-};
+	/* tune status */
+	uint8_t tune_state;
+	/* signal strength */
+	int16_t signal_strength;
+	/* packet error rate 10^-4 */
+	uint16_t PER;
+	/* bit error rate 10^-4 */
+	uint16_t BER;
+} __packed;
 
 struct as10x_demod_stats {
-   /* frame counter */
-   uint32_t frame_count;
-   /* Bad frame counter */
-   uint32_t bad_frame_count;
-   /* Number of wrong bytes fixed by Reed-Solomon */
-   uint32_t bytes_fixed_by_rs;
-   /* Averaged MER */
-   uint16_t mer;
-   /* statistics calculation state indicator (started or not) */
-   uint8_t has_started;
-};
+	/* frame counter */
+	uint32_t frame_count;
+	/* Bad frame counter */
+	uint32_t bad_frame_count;
+	/* Number of wrong bytes fixed by Reed-Solomon */
+	uint32_t bytes_fixed_by_rs;
+	/* Averaged MER */
+	uint16_t mer;
+	/* statistics calculation state indicator (started or not) */
+	uint8_t has_started;
+} __packed;
 
 struct as10x_ts_filter {
-   uint16_t pid;  /** valid PID value 0x00 : 0x2000 */
-   uint8_t  type; /** Red TS_PID_TYPE_<N> values */
-   uint8_t  idx;  /** index in filtering table */
-};
+	uint16_t pid;  /* valid PID value 0x00 : 0x2000 */
+	uint8_t  type; /* Red TS_PID_TYPE_<N> values */
+	uint8_t  idx;  /* index in filtering table */
+} __packed;
 
 struct as10x_register_value {
-   uint8_t       mode;
-   union {
-      uint8_t    value8;    /* 8 bit value */
-      uint16_t   value16;   /* 16 bit value */
-      uint32_t   value32;   /* 32 bit value */
-   }u;
-};
-
-#pragma pack()
+	uint8_t mode;
+	union {
+		uint8_t  value8;   /* 8 bit value */
+		uint16_t value16;  /* 16 bit value */
+		uint32_t value32;  /* 32 bit value */
+	} u;
+} __packed;
 
 struct as10x_register_addr {
-   /* register addr */
-   uint32_t addr;
-   /* register mode access */
-   uint8_t mode;
+	/* register addr */
+	uint32_t addr;
+	/* register mode access */
+	uint8_t mode;
 };
 
-
 #endif
diff --git a/drivers/staging/media/easycap/easycap.h b/drivers/staging/media/easycap/easycap.h
index 7b256a9..a007e74 100644
--- a/drivers/staging/media/easycap/easycap.h
+++ b/drivers/staging/media/easycap/easycap.h
@@ -98,7 +98,6 @@
 #define EASYCAP_DRIVER_VERSION "0.9.01"
 #define EASYCAP_DRIVER_DESCRIPTION "easycapdc60"
 
-#define USB_SKEL_MINOR_BASE     192
 #define DONGLE_MANY 8
 #define INPUT_MANY 6
 /*---------------------------------------------------------------------------*/
@@ -324,8 +323,6 @@
 	int lost[INPUT_MANY];
 	int merit[180];
 
-	long long int dnbydt;
-
 	int    video_interface;
 	int    video_altsetting_on;
 	int    video_altsetting_off;
@@ -353,7 +350,6 @@
 	u8 *pcache;
 	int video_mt;
 	int audio_mt;
-	long long audio_bytes;
 	u32 isequence;
 
 	int vma_many;
@@ -450,9 +446,6 @@
  *  SOUND PROPERTIES
  */
 /*---------------------------------------------------------------------------*/
-
-	int audio_buffer_many;
-
 	int allocation_audio_urb;
 	int allocation_audio_page;
 	int allocation_audio_struct;
@@ -469,72 +462,53 @@
  *  VIDEO FUNCTION PROTOTYPES
  */
 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+int easycap_newinput(struct easycap *, int);
+void easycap_testcard(struct easycap *, int);
+int easycap_isdongle(struct easycap *);
+
 long easycap_unlocked_ioctl(struct file *, unsigned int, unsigned long);
-int              easycap_dqbuf(struct easycap *, int);
-int              submit_video_urbs(struct easycap *);
-int              kill_video_urbs(struct easycap *);
-int              field2frame(struct easycap *);
-int              redaub(struct easycap *, void *, void *,
-						int, int, u8, u8, bool);
-void             easycap_testcard(struct easycap *, int);
-int              fillin_formats(void);
-int              newinput(struct easycap *, int);
-int              adjust_standard(struct easycap *, v4l2_std_id);
-int              adjust_format(struct easycap *, u32, u32, u32,
-								int, bool);
-int              adjust_brightness(struct easycap *, int);
-int              adjust_contrast(struct easycap *, int);
-int              adjust_saturation(struct easycap *, int);
-int              adjust_hue(struct easycap *, int);
-int              adjust_volume(struct easycap *, int);
+
+int easycap_video_dqbuf(struct easycap *, int);
+int easycap_video_submit_urbs(struct easycap *);
+int easycap_video_kill_urbs(struct easycap *);
+int easycap_video_fillin_formats(void);
+
+int adjust_standard(struct easycap *, v4l2_std_id);
+int adjust_format(struct easycap *, u32, u32, u32, int, bool);
+int adjust_brightness(struct easycap *, int);
+int adjust_contrast(struct easycap *, int);
+int adjust_saturation(struct easycap *, int);
+int adjust_hue(struct easycap *, int);
 /*---------------------------------------------------------------------------*/
 /*
  *  AUDIO FUNCTION PROTOTYPES
  */
 /*---------------------------------------------------------------------------*/
-int		easycap_alsa_probe(struct easycap *);
-void            easycap_alsa_complete(struct urb *);
-
-int              easycap_sound_setup(struct easycap *);
-int              submit_audio_urbs(struct easycap *);
-int              kill_audio_urbs(struct easycap *);
-void             easyoss_testtone(struct easycap *, int);
-int              audio_setup(struct easycap *);
+int easycap_alsa_probe(struct easycap *);
+int easycap_audio_kill_urbs(struct easycap *);
+void easycap_alsa_complete(struct urb *);
 /*---------------------------------------------------------------------------*/
 /*
  *  LOW-LEVEL FUNCTION PROTOTYPES
  */
 /*---------------------------------------------------------------------------*/
-int              audio_gainget(struct usb_device *);
-int              audio_gainset(struct usb_device *, s8);
+int easycap_audio_gainset(struct usb_device *, s8);
+int easycap_audio_setup(struct easycap *);
 
-int              set_interface(struct usb_device *, u16);
-int              wakeup_device(struct usb_device *);
-int              confirm_resolution(struct usb_device *);
-int              confirm_stream(struct usb_device *);
+int easycap_wakeup_device(struct usb_device *);
 
-int              setup_stk(struct usb_device *, bool);
-int              setup_saa(struct usb_device *, bool);
-int              setup_vt(struct usb_device *);
-int              check_stk(struct usb_device *, bool);
-int              check_saa(struct usb_device *, bool);
-int              ready_saa(struct usb_device *);
-int              merit_saa(struct usb_device *);
-int              check_vt(struct usb_device *);
-int              select_input(struct usb_device *, int, int);
-int              set_resolution(struct usb_device *,
-						u16, u16, u16, u16);
+int setup_stk(struct usb_device *, bool);
+int setup_saa(struct usb_device *, bool);
+int ready_saa(struct usb_device *);
+int merit_saa(struct usb_device *);
+int check_vt(struct usb_device *);
+int select_input(struct usb_device *, int, int);
+int set_resolution(struct usb_device *, u16, u16, u16, u16);
 
-int              read_saa(struct usb_device *, u16);
-int              read_stk(struct usb_device *, u32);
-int              write_saa(struct usb_device *, u16, u16);
-int              write_000(struct usb_device *, u16, u16);
-int              start_100(struct usb_device *);
-int              stop_100(struct usb_device *);
-int              write_300(struct usb_device *);
-int              read_vt(struct usb_device *, u16);
-int              write_vt(struct usb_device *, u16, u16);
-int		isdongle(struct easycap *);
+int read_saa(struct usb_device *, u16);
+int write_saa(struct usb_device *, u16, u16);
+int start_100(struct usb_device *);
+int stop_100(struct usb_device *);
 /*---------------------------------------------------------------------------*/
 
 
@@ -588,7 +562,6 @@
 extern const struct easycap_standard easycap_standard[];
 extern struct easycap_format easycap_format[];
 extern struct v4l2_queryctrl easycap_control[];
-extern struct usb_driver easycap_usb_driver;
 extern struct easycap_dongle easycapdc60_dongle[];
 
 #endif /* !__EASYCAP_H__  */
diff --git a/drivers/staging/media/easycap/easycap_ioctl.c b/drivers/staging/media/easycap/easycap_ioctl.c
index c99addf..9413b37 100644
--- a/drivers/staging/media/easycap/easycap_ioctl.c
+++ b/drivers/staging/media/easycap/easycap_ioctl.c
@@ -25,7 +25,6 @@
 */
 /*****************************************************************************/
 
-#include <linux/version.h>
 #include "easycap.h"
 
 /*--------------------------------------------------------------------------*/
@@ -125,7 +124,7 @@
 	}
 	if (peasycap->video_isoc_streaming) {
 		resubmit = true;
-		kill_video_urbs(peasycap);
+		easycap_video_kill_urbs(peasycap);
 	} else
 		resubmit = false;
 /*--------------------------------------------------------------------------*/
@@ -331,7 +330,7 @@
 			    "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
 	}
 	if (resubmit)
-		submit_video_urbs(peasycap);
+		easycap_video_submit_urbs(peasycap);
 	return 0;
 }
 /*****************************************************************************/
@@ -558,7 +557,7 @@
 		peasycap->bytesperpixel * peasycap->width * peasycap->height;
 	if (peasycap->video_isoc_streaming) {
 		resubmit = true;
-		kill_video_urbs(peasycap);
+		easycap_video_kill_urbs(peasycap);
 	} else
 		resubmit = false;
 /*---------------------------------------------------------------------------*/
@@ -622,7 +621,7 @@
 	}
 /*---------------------------------------------------------------------------*/
 	if (resubmit)
-		submit_video_urbs(peasycap);
+		easycap_video_submit_urbs(peasycap);
 
 	return peasycap_best_format - easycap_format;
 }
@@ -667,16 +666,15 @@
 				peasycap->inputset[peasycap->input].brightness_ok = 1;
 			} else
 				JOM(8, "%i=peasycap->input\n", peasycap->input);
+
 			mood = 0x00FF & (unsigned int)peasycap->brightness;
-			if (!write_saa(peasycap->pusb_device, 0x0A, mood)) {
-				SAM("adjusting brightness to  0x%02X\n", mood);
-				return 0;
-			} else {
+			if (write_saa(peasycap->pusb_device, 0x0A, mood)) {
 				SAM("WARNING: failed to adjust brightness "
 				    "to 0x%02X\n", mood);
 				return -ENOENT;
 			}
-			break;
+			SAM("adjusting brightness to  0x%02X\n", mood);
+			return 0;
 		}
 		i1++;
 	}
@@ -726,15 +724,13 @@
 				JOM(8, "%i=peasycap->input\n", peasycap->input);
 
 			mood = 0x00FF & (unsigned int) (peasycap->contrast - 128);
-			if (!write_saa(peasycap->pusb_device, 0x0B, mood)) {
-				SAM("adjusting contrast to  0x%02X\n", mood);
-				return 0;
-			} else {
+			if (write_saa(peasycap->pusb_device, 0x0B, mood)) {
 				SAM("WARNING: failed to adjust contrast to "
 				    "0x%02X\n", mood);
 				return -ENOENT;
 			}
-			break;
+			SAM("adjusting contrast to  0x%02X\n", mood);
+			return 0;
 		}
 		i1++;
 	}
@@ -784,14 +780,13 @@
 			} else
 				JOM(8, "%i=peasycap->input\n", peasycap->input);
 			mood = 0x00FF & (unsigned int) (peasycap->saturation - 128);
-			if (!write_saa(peasycap->pusb_device, 0x0C, mood)) {
-				SAM("adjusting saturation to  0x%02X\n", mood);
-				return 0;
-			} else {
+			if (write_saa(peasycap->pusb_device, 0x0C, mood)) {
 				SAM("WARNING: failed to adjust saturation to "
 				    "0x%02X\n", mood);
 				return -ENOENT;
 			}
+			SAM("adjusting saturation to  0x%02X\n", mood);
+			return 0;
 			break;
 		}
 		i1++;
@@ -839,13 +834,12 @@
 				JOM(8, "%i=peasycap->input\n", peasycap->input);
 			i2 = peasycap->hue - 128;
 			mood = 0x00FF & ((int) i2);
-			if (!write_saa(peasycap->pusb_device, 0x0D, mood)) {
-				SAM("adjusting hue to  0x%02X\n", mood);
-				return 0;
-			} else {
+			if (write_saa(peasycap->pusb_device, 0x0D, mood)) {
 				SAM("WARNING: failed to adjust hue to 0x%02X\n", mood);
 				return -ENOENT;
 			}
+			SAM("adjusting hue to  0x%02X\n", mood);
+			return 0;
 			break;
 		}
 		i1++;
@@ -854,7 +848,7 @@
 	return -ENOENT;
 }
 /*****************************************************************************/
-int adjust_volume(struct easycap *peasycap, int value)
+static int adjust_volume(struct easycap *peasycap, int value)
 {
 	s8 mood;
 	int i1;
@@ -885,15 +879,13 @@
 			mood = (16 > peasycap->volume) ? 16 :
 				((31 < peasycap->volume) ? 31 :
 				  (s8) peasycap->volume);
-			if (!audio_gainset(peasycap->pusb_device, mood)) {
-				SAM("adjusting volume to 0x%02X\n", mood);
-				return 0;
-			} else {
+			if (!easycap_audio_gainset(peasycap->pusb_device, mood)) {
 				SAM("WARNING: failed to adjust volume to "
 				    "0x%2X\n", mood);
 				return -ENOENT;
 			}
-			break;
+			SAM("adjusting volume to 0x%02X\n", mood);
+			return 0;
 		}
 		i1++;
 	}
@@ -971,7 +963,7 @@
 		SAM("ERROR: peasycap->pusb_device is NULL\n");
 		return -EFAULT;
 	}
-	kd = isdongle(peasycap);
+	kd = easycap_isdongle(peasycap);
 	if (0 <= kd && DONGLE_MANY > kd) {
 		if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) {
 			SAY("ERROR: cannot lock "
@@ -986,7 +978,7 @@
  *  IF NECESSARY, BAIL OUT.
  */
 /*---------------------------------------------------------------------------*/
-		if (kd != isdongle(peasycap))
+		if (kd != easycap_isdongle(peasycap))
 			return -ERESTARTSYS;
 		if (!file) {
 			SAY("ERROR:  file is NULL\n");
@@ -1226,7 +1218,7 @@
 			return -EINVAL;
 		}
 
-		rc = newinput(peasycap, (int)index);
+		rc = easycap_newinput(peasycap, (int)index);
 		if (0 == rc) {
 			JOM(8, "newinput(.,%i) OK\n", (int)index);
 		} else {
@@ -2209,7 +2201,7 @@
 
 		if (!peasycap->polled) {
 			do {
-				rcdq = easycap_dqbuf(peasycap, 0);
+				rcdq = easycap_video_dqbuf(peasycap, 0);
 				if (-EIO == rcdq) {
 					JOM(8, "returning -EIO because "
 					    "dqbuf() returned -EIO\n");
@@ -2313,7 +2305,7 @@
 			mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
 			return -EFAULT;
 		}
-		submit_video_urbs(peasycap);
+		easycap_video_submit_urbs(peasycap);
 		peasycap->video_idle = 0;
 		peasycap->audio_idle = 0;
 		peasycap->video_eof = 0;
diff --git a/drivers/staging/media/easycap/easycap_low.c b/drivers/staging/media/easycap/easycap_low.c
index 0385735..0380bab 100644
--- a/drivers/staging/media/easycap/easycap_low.c
+++ b/drivers/staging/media/easycap/easycap_low.c
@@ -40,6 +40,7 @@
 
 #include "easycap.h"
 
+
 #define GET(X, Y, Z) do { \
 	int __rc; \
 	*(Z) = (u16)0; \
@@ -59,9 +60,9 @@
 
 /*--------------------------------------------------------------------------*/
 static const struct stk1160config {
-	int reg;
-	int set;
-} stk1160configPAL[256] = {
+	u16 reg;
+	u16 set;
+} stk1160configPAL[] = {
 		{0x000, 0x0098},
 		{0x002, 0x0093},
 
@@ -103,7 +104,7 @@
 		{0xFFF, 0xFFFF}
 };
 /*--------------------------------------------------------------------------*/
-static const struct stk1160config stk1160configNTSC[256] = {
+static const struct stk1160config stk1160configNTSC[] = {
 		{0x000, 0x0098},
 		{0x002, 0x0093},
 
@@ -146,9 +147,9 @@
 };
 /*--------------------------------------------------------------------------*/
 static const struct saa7113config {
-	int reg;
-	int set;
-} saa7113configPAL[256] = {
+	u8 reg;
+	u8 set;
+} saa7113configPAL[] = {
 		{0x01, 0x08},
 		{0x02, 0x80},
 		{0x03, 0x33},
@@ -202,7 +203,7 @@
 		{0xFF, 0xFF}
 };
 /*--------------------------------------------------------------------------*/
-static const struct saa7113config saa7113configNTSC[256] = {
+static const struct saa7113config saa7113configNTSC[] = {
 		{0x01, 0x08},
 		{0x02, 0x80},
 		{0x03, 0x33},
@@ -355,101 +356,6 @@
 }
 
 /****************************************************************************/
-int confirm_resolution(struct usb_device *p)
-{
-	u8 get0, get1, get2, get3, get4, get5, get6, get7;
-
-	if (!p)
-		return -ENODEV;
-	GET(p, 0x0110, &get0);
-	GET(p, 0x0111, &get1);
-	GET(p, 0x0112, &get2);
-	GET(p, 0x0113, &get3);
-	GET(p, 0x0114, &get4);
-	GET(p, 0x0115, &get5);
-	GET(p, 0x0116, &get6);
-	GET(p, 0x0117, &get7);
-	JOT(8,  "0x%03X, 0x%03X, "
-		"0x%03X, 0x%03X, "
-		"0x%03X, 0x%03X, "
-		"0x%03X, 0x%03X\n",
-		get0, get1, get2, get3, get4, get5, get6, get7);
-	JOT(8,  "....cf PAL_720x526: "
-		"0x%03X, 0x%03X, "
-		"0x%03X, 0x%03X, "
-		"0x%03X, 0x%03X, "
-		"0x%03X, 0x%03X\n",
-		0x000, 0x000, 0x001, 0x000, 0x5A0, 0x005, 0x121, 0x001);
-	JOT(8,  "....cf PAL_704x526: "
-		"0x%03X, 0x%03X, "
-		"0x%03X, 0x%03X, "
-		"0x%03X, 0x%03X, "
-		"0x%03X, 0x%03X\n",
-		0x004, 0x000, 0x001, 0x000, 0x584, 0x005, 0x121, 0x001);
-	JOT(8,  "....cf VGA_640x480: "
-		"0x%03X, 0x%03X, "
-		"0x%03X, 0x%03X, "
-		"0x%03X, 0x%03X, "
-		"0x%03X, 0x%03X\n",
-		0x008, 0x000, 0x020, 0x000, 0x508, 0x005, 0x110, 0x001);
-	return 0;
-}
-/****************************************************************************/
-int confirm_stream(struct usb_device *p)
-{
-	u16 get2;
-	u8 igot;
-
-	if (!p)
-		return -ENODEV;
-	GET(p, 0x0100, &igot);  get2 = 0x80 & igot;
-	if (0x80 == get2)
-		JOT(8, "confirm_stream:  OK\n");
-	else
-		JOT(8, "confirm_stream:  STUCK\n");
-	return 0;
-}
-/****************************************************************************/
-int setup_stk(struct usb_device *p, bool ntsc)
-{
-	int i;
-	const struct stk1160config *cfg;
-	if (!p)
-		return -ENODEV;
-	cfg = (ntsc) ? stk1160configNTSC : stk1160configPAL;
-	for (i = 0; cfg[i].reg != 0xFFF; i++)
-		SET(p, cfg[i].reg, cfg[i].set);
-
-	write_300(p);
-
-	return 0;
-}
-/****************************************************************************/
-int setup_saa(struct usb_device *p, bool ntsc)
-{
-	int i, ir;
-	const struct saa7113config *cfg;
-	if (!p)
-		return -ENODEV;
-	cfg = (ntsc) ?  saa7113configNTSC : saa7113configPAL;
-	for (i = 0; cfg[i].reg != 0xFF; i++)
-		ir = write_saa(p, cfg[i].reg, cfg[i].set);
-	return 0;
-}
-/****************************************************************************/
-int write_000(struct usb_device *p, u16 set2, u16 set0)
-{
-	u8 igot0, igot2;
-
-	if (!p)
-		return -ENODEV;
-	GET(p, 0x0002, &igot2);
-	GET(p, 0x0000, &igot0);
-	SET(p, 0x0002, set2);
-	SET(p, 0x0000, set0);
-	return 0;
-}
-/****************************************************************************/
 int write_saa(struct usb_device *p, u16 reg0, u16 set0)
 {
 	if (!p)
@@ -470,8 +376,7 @@
  *  REGISTER 504:  TARGET ADDRESS ON VT1612A
  */
 /*--------------------------------------------------------------------------*/
-int
-write_vt(struct usb_device *p, u16 reg0, u16 set0)
+static int write_vt(struct usb_device *p, u16 reg0, u16 set0)
 {
 	u8 igot;
 	u16 got502, got503;
@@ -508,7 +413,7 @@
  *  REGISTER 504:  TARGET ADDRESS ON VT1612A
  */
 /*--------------------------------------------------------------------------*/
-int read_vt(struct usb_device *p, u16 reg0)
+static int read_vt(struct usb_device *p, u16 reg0)
 {
 	u8 igot;
 	u16 got502, got503;
@@ -532,7 +437,7 @@
  *  THESE APPEAR TO HAVE NO EFFECT ON EITHER VIDEO OR AUDIO.
  */
 /*--------------------------------------------------------------------------*/
-int write_300(struct usb_device *p)
+static int write_300(struct usb_device *p)
 {
 	if (!p)
 		return -ENODEV;
@@ -545,32 +450,36 @@
 	return 0;
 }
 /****************************************************************************/
-/*--------------------------------------------------------------------------*/
-/*
- *  NOTE: THE FOLLOWING IS NOT CHECKED:
- *  REGISTER 0x0F, WHICH IS INVOLVED IN CHROMINANCE AUTOMATIC GAIN CONTROL.
- */
-/*--------------------------------------------------------------------------*/
-int check_saa(struct usb_device *p, bool ntsc)
+/****************************************************************************/
+int setup_stk(struct usb_device *p, bool ntsc)
 {
-	int i, ir, rc = 0;
-	struct saa7113config const *cfg;
+	int i;
+	const struct stk1160config *cfg;
 	if (!p)
 		return -ENODEV;
+	cfg = (ntsc) ? stk1160configNTSC : stk1160configPAL;
+	for (i = 0; cfg[i].reg != 0xFFF; i++)
+		SET(p, cfg[i].reg, cfg[i].set);
 
-	cfg = (ntsc) ? saa7113configNTSC : saa7113configPAL;
+	write_300(p);
+
+	return 0;
+}
+/****************************************************************************/
+int setup_saa(struct usb_device *p, bool ntsc)
+{
+	int i, rc;
+	const struct saa7113config *cfg;
+	if (!p)
+		return -ENODEV;
+	cfg = (ntsc) ?  saa7113configNTSC : saa7113configPAL;
 	for (i = 0; cfg[i].reg != 0xFF; i++) {
-		if (0x0F == cfg[i].reg)
-			continue;
-		ir = read_saa(p, cfg[i].reg);
-		if (ir != cfg[i].set) {
-			SAY("SAA register 0x%02X has 0x%02X, expected 0x%02X\n",
-				cfg[i].reg, ir, cfg[i].set);
-				rc--;
-		}
+		rc = write_saa(p, cfg[i].reg, cfg[i].set);
+		if (rc)
+			dev_err(&p->dev,
+				"Failed to set SAA register %d", cfg[i].reg);
 	}
-
-	return (rc < -8) ? rc : 0;
+	return 0;
 }
 /****************************************************************************/
 int merit_saa(struct usb_device *p)
@@ -609,60 +518,22 @@
 		msleep(marktime);
 		j++;
 	}
+
 	if (max == j)
 		return -1;
-	else {
-		if (0x20 & rc) {
-			rate = 2;
-			JOT(8, "hardware detects 60 Hz\n");
-		} else {
-			rate = 0;
-			JOT(8, "hardware detects 50 Hz\n");
-		}
-		if (0x80 & rc)
-			JOT(8, "hardware detects interlacing\n");
-		else {
-			rate++;
-			JOT(8, "hardware detects no interlacing\n");
-		}
+
+	if (0x20 & rc) {
+		rate = 2;
+		JOT(8, "hardware detects 60 Hz\n");
+	} else {
+		rate = 0;
+		JOT(8, "hardware detects 50 Hz\n");
 	}
-	return 0;
-}
-/****************************************************************************/
-/*--------------------------------------------------------------------------*/
-/*
- *  NOTE: THE FOLLOWING ARE NOT CHECKED:
- *  REGISTERS 0x000, 0x002:  FUNCTIONALITY IS NOT KNOWN
- *  REGISTER  0x100:  ACCEPT ALSO (0x80 | stk1160config....[.].set)
- */
-/*--------------------------------------------------------------------------*/
-int check_stk(struct usb_device *p, bool ntsc)
-{
-	int i, ir;
-	const struct stk1160config *cfg;
-
-	if (!p)
-		return -ENODEV;
-	cfg = (ntsc) ? stk1160configNTSC : stk1160configPAL;
-
-	for (i = 0; 0xFFF != cfg[i].reg; i++) {
-		if (0x000 == cfg[i].reg || 0x002 == cfg[i].reg)
-			continue;
-
-
-		ir = read_stk(p, cfg[i].reg);
-		if (0x100 == cfg[i].reg) {
-			if ((ir != (0xFF & cfg[i].set)) &&
-			    (ir != (0x80 | (0xFF & cfg[i].set))) &&
-			    (0xFFFF != cfg[i].set)) {
-				SAY("STK reg[0x%03X]=0x%02X expected 0x%02X\n",
-					cfg[i].reg, ir, cfg[i].set);
-			}
-			continue;
-		}
-		if ((ir != (0xFF & cfg[i].set)) && (0xFFFF != cfg[i].set))
-			SAY("STK register 0x%03X has 0x%02X,expected 0x%02X\n",
-				cfg[i].reg, ir, cfg[i].set);
+	if (0x80 & rc)
+		JOT(8, "hardware detects interlacing\n");
+	else {
+		rate++;
+		JOT(8, "hardware detects no interlacing\n");
 	}
 	return 0;
 }
@@ -682,7 +553,7 @@
 	return igot;
 }
 /****************************************************************************/
-int read_stk(struct usb_device *p, u32 reg0)
+static int read_stk(struct usb_device *p, u32 reg0)
 {
 	u8 igot;
 
@@ -692,27 +563,7 @@
 	GET(p, reg0, &igot);
 	return igot;
 }
-/****************************************************************************/
-/*--------------------------------------------------------------------------*/
-/*
- *    HARDWARE    USERSPACE INPUT NUMBER   PHYSICAL INPUT   DRIVER input VALUE
- *
- *  CVBS+S-VIDEO           0 or 1              CVBS                 1
- *   FOUR-CVBS             0 or 1              CVBS1                1
- *   FOUR-CVBS                2                CVBS2                2
- *   FOUR-CVBS                3                CVBS3                3
- *   FOUR-CVBS                4                CVBS4                4
- *  CVBS+S-VIDEO              5               S-VIDEO               5
- *
- *  WHEN 5==input THE ARGUMENT mode MUST ALSO BE SUPPLIED:
- *
- *     mode  7   => GAIN TO BE SET EXPLICITLY USING REGISTER 0x05 (UNTESTED)
- *     mode  9   => USE AUTOMATIC GAIN CONTROL (DEFAULT)
- *
-*/
-/*---------------------------------------------------------------------------*/
-int
-select_input(struct usb_device *p, int input, int mode)
+int select_input(struct usb_device *p, int input, int mode)
 {
 	int ir;
 
@@ -877,10 +728,11 @@
 /****************************************************************************/
 /****************************************************************************/
 /*****************************************************************************/
-int wakeup_device(struct usb_device *pusb_device)
+int easycap_wakeup_device(struct usb_device *pusb_device)
 {
 	if (!pusb_device)
 		return -ENODEV;
+
 	return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),
 			USB_REQ_SET_FEATURE,
 			USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
@@ -888,8 +740,7 @@
 			0, NULL, 0, 50000);
 }
 /*****************************************************************************/
-int
-audio_setup(struct easycap *peasycap)
+int easycap_audio_setup(struct easycap *peasycap)
 {
 	struct usb_device *pusb_device;
 	u8 buffer[1];
@@ -970,7 +821,7 @@
  *  SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN.
 */
 /*---------------------------------------------------------------------------*/
-	if (0 != audio_gainset(pusb_device, peasycap->gain))
+	if (easycap_audio_gainset(pusb_device, peasycap->gain))
 		SAY("ERROR: audio_gainset() failed\n");
 	check_vt(pusb_device);
 	return 0;
@@ -1047,7 +898,7 @@
  *        31                12.0                  22.5            34.5
 */
 /*---------------------------------------------------------------------------*/
-int audio_gainset(struct usb_device *pusb_device, s8 loud)
+int easycap_audio_gainset(struct usb_device *pusb_device, s8 loud)
 {
 	int igot;
 	u8 tmp;
@@ -1115,15 +966,3 @@
 	return 0;
 }
 /*****************************************************************************/
-int audio_gainget(struct usb_device *pusb_device)
-{
-	int igot;
-
-	if (!pusb_device)
-		return -ENODEV;
-	igot = read_vt(pusb_device, 0x001C);
-	if (0 > igot)
-		SAY("ERROR: failed to read VT1612A register 0x1C\n");
-	return igot;
-}
-/*****************************************************************************/
diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c
index a45c0b5..8ff5f38 100644
--- a/drivers/staging/media/easycap/easycap_main.c
+++ b/drivers/staging/media/easycap/easycap_main.c
@@ -66,6 +66,10 @@
 static struct mutex mutex_dongle;
 static void easycap_complete(struct urb *purb);
 static int reset(struct easycap *peasycap);
+static int field2frame(struct easycap *peasycap);
+static int redaub(struct easycap *peasycap,
+		void *pad, void *pex, int much, int more,
+		u8 mask, u8 margin, bool isuy);
 
 const char *strerror(int err)
 {
@@ -109,23 +113,13 @@
 #undef ERRNOSTR
 }
 
-/*---------------------------------------------------------------------------*/
-/*
- *  PARAMETERS USED WHEN REGISTERING THE VIDEO INTERFACE
- *
- *  NOTE: SOME KERNELS IGNORE usb_class_driver.minor_base, AS MENTIONED BY
- *        CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGE 253.
- *        THIS IS THE CASE FOR OpenSUSE.
- */
-/*---------------------------------------------------------------------------*/
-/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
 /****************************************************************************/
 /*---------------------------------------------------------------------------*/
 /*
  *  THIS ROUTINE DOES NOT DETECT DUPLICATE OCCURRENCES OF POINTER peasycap
 */
 /*---------------------------------------------------------------------------*/
-int isdongle(struct easycap *peasycap)
+int easycap_isdongle(struct easycap *peasycap)
 {
 	int k;
 	if (!peasycap)
@@ -161,14 +155,13 @@
 	if (!peasycap->pusb_device) {
 		SAM("ERROR: peasycap->pusb_device is NULL\n");
 		return -EFAULT;
-	} else {
-		JOM(16, "peasycap->pusb_device=%p\n", peasycap->pusb_device);
 	}
+
+	JOM(16, "peasycap->pusb_device=%p\n", peasycap->pusb_device);
+
 	file->private_data = peasycap;
-	rc = wakeup_device(peasycap->pusb_device);
-	if (0 == rc)
-		JOM(8, "wakeup_device() OK\n");
-	else {
+	rc = easycap_wakeup_device(peasycap->pusb_device);
+	if (rc) {
 		SAM("ERROR: wakeup_device() rc = %i\n", rc);
 		if (-ENODEV == rc)
 			SAM("ERROR: wakeup_device() returned -ENODEV\n");
@@ -176,6 +169,7 @@
 			SAM("ERROR: wakeup_device() rc = %i\n", rc);
 		return rc;
 	}
+	JOM(8, "wakeup_device() OK\n");
 	peasycap->input = 0;
 	rc = reset(peasycap);
 	if (rc) {
@@ -303,7 +297,7 @@
 	peasycap->saturation = -8192;
 	peasycap->hue = -8192;
 
-	rc = newinput(peasycap, input);
+	rc = easycap_newinput(peasycap, input);
 
 	if (rc) {
 		SAM("ERROR: newinput(.,%i) rc = %i\n", rc, input);
@@ -364,8 +358,7 @@
  *      SO IT SHOULD WRITE ONLY SPARINGLY TO THE LOGFILE.
 */
 /*---------------------------------------------------------------------------*/
-int
-newinput(struct easycap *peasycap, int input)
+int easycap_newinput(struct easycap *peasycap, int input)
 {
 	int rc, k, m, mood, off;
 	int inputnow, video_idlenow, audio_idlenow;
@@ -397,7 +390,7 @@
 	peasycap->audio_idle = 1;
 	if (peasycap->video_isoc_streaming) {
 		resubmit = true;
-		kill_video_urbs(peasycap);
+		easycap_video_kill_urbs(peasycap);
 	} else {
 		resubmit = false;
 	}
@@ -532,7 +525,7 @@
 		return -EFAULT;
 	}
 	if (resubmit)
-		submit_video_urbs(peasycap);
+		easycap_video_submit_urbs(peasycap);
 
 	peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1;
 	peasycap->video_idle = video_idlenow;
@@ -542,7 +535,7 @@
 	return 0;
 }
 /*****************************************************************************/
-int submit_video_urbs(struct easycap *peasycap)
+int easycap_video_submit_urbs(struct easycap *peasycap)
 {
 	struct data_urb *pdata_urb;
 	struct urb *purb;
@@ -616,43 +609,53 @@
 			peasycap->video_eof = 1;
 		}
 
-		if (isbad) {
-			JOM(4, "attempting cleanup instead of submitting\n");
-			list_for_each(plist_head, (peasycap->purb_video_head)) {
-				pdata_urb = list_entry(plist_head,
-						struct data_urb, list_head);
-				if (pdata_urb) {
-					purb = pdata_urb->purb;
-					if (purb)
-						usb_kill_urb(purb);
-				}
-			}
-			peasycap->video_isoc_streaming = 0;
-		} else {
+		if (isbad)
+			easycap_video_kill_urbs(peasycap);
+		else
 			peasycap->video_isoc_streaming = 1;
-			JOM(4, "submitted %i video urbs\n", m);
-		}
 	} else {
 		JOM(4, "already streaming video urbs\n");
 	}
 	return 0;
 }
 /*****************************************************************************/
-int kill_video_urbs(struct easycap *peasycap)
+int easycap_audio_kill_urbs(struct easycap *peasycap)
 {
 	int m;
 	struct list_head *plist_head;
 	struct data_urb *pdata_urb;
 
-	if (!peasycap) {
-		SAY("ERROR: peasycap is NULL\n");
+	if (!peasycap->audio_isoc_streaming)
+		return 0;
+
+	if (!peasycap->purb_audio_head) {
+		SAM("ERROR: peasycap->purb_audio_head is NULL\n");
 		return -EFAULT;
 	}
-	if (!peasycap->video_isoc_streaming) {
-		JOM(8, "%i=video_isoc_streaming, no video urbs killed\n",
-			peasycap->video_isoc_streaming);
-		return 0;
+
+	peasycap->audio_isoc_streaming = 0;
+	m = 0;
+	list_for_each(plist_head, peasycap->purb_audio_head) {
+		pdata_urb = list_entry(plist_head, struct data_urb, list_head);
+		if (pdata_urb && pdata_urb->purb) {
+			usb_kill_urb(pdata_urb->purb);
+			m++;
+		}
 	}
+
+	JOM(4, "%i audio urbs killed\n", m);
+
+	return 0;
+}
+int easycap_video_kill_urbs(struct easycap *peasycap)
+{
+	int m;
+	struct list_head *plist_head;
+	struct data_urb *pdata_urb;
+
+	if (!peasycap->video_isoc_streaming)
+		return 0;
+
 	if (!peasycap->purb_video_head) {
 		SAM("ERROR: peasycap->purb_video_head is NULL\n");
 		return -EFAULT;
@@ -690,8 +693,8 @@
 		SAY("ending unsuccessfully\n");
 		return -EFAULT;
 	}
-	if (0 != kill_video_urbs(peasycap)) {
-		SAM("ERROR: kill_video_urbs() failed\n");
+	if (easycap_video_kill_urbs(peasycap)) {
+		SAM("ERROR: easycap_video_kill_urbs() failed\n");
 		return -EFAULT;
 	}
 	JOM(4, "ending successfully\n");
@@ -727,27 +730,22 @@
 		SAM("ERROR: peasycap is NULL: cannot perform deletions\n");
 		return;
 	}
-	kd = isdongle(peasycap);
+	kd = easycap_isdongle(peasycap);
 /*---------------------------------------------------------------------------*/
 /*
  *  FREE VIDEO.
  */
 /*---------------------------------------------------------------------------*/
 	if (peasycap->purb_video_head) {
-		JOM(4, "freeing video urbs\n");
 		m = 0;
-		list_for_each(plist_head, (peasycap->purb_video_head)) {
+		list_for_each(plist_head, peasycap->purb_video_head) {
 			pdata_urb = list_entry(plist_head,
 						struct data_urb, list_head);
-			if (!pdata_urb) {
-				JOM(4, "ERROR: pdata_urb is NULL\n");
-			} else {
-				if (pdata_urb->purb) {
-					usb_free_urb(pdata_urb->purb);
-					pdata_urb->purb = NULL;
-					peasycap->allocation_video_urb -= 1;
-					m++;
-				}
+			if (pdata_urb && pdata_urb->purb) {
+				usb_free_urb(pdata_urb->purb);
+				pdata_urb->purb = NULL;
+				peasycap->allocation_video_urb--;
+				m++;
 			}
 		}
 
@@ -763,7 +761,6 @@
 				peasycap->allocation_video_struct -=
 						sizeof(struct data_urb);
 				kfree(pdata_urb);
-				pdata_urb = NULL;
 				m++;
 			}
 		}
@@ -828,15 +825,11 @@
 		list_for_each(plist_head, (peasycap->purb_audio_head)) {
 			pdata_urb = list_entry(plist_head,
 					struct data_urb, list_head);
-			if (!pdata_urb)
-				JOM(4, "ERROR: pdata_urb is NULL\n");
-			else {
-				if (pdata_urb->purb) {
-					usb_free_urb(pdata_urb->purb);
-					pdata_urb->purb = NULL;
-					peasycap->allocation_audio_urb -= 1;
-					m++;
-				}
+			if (pdata_urb && pdata_urb->purb) {
+				usb_free_urb(pdata_urb->purb);
+				pdata_urb->purb = NULL;
+				peasycap->allocation_audio_urb--;
+				m++;
 			}
 		}
 		JOM(4, "%i audio urbs freed\n", m);
@@ -851,7 +844,6 @@
 				peasycap->allocation_audio_struct -=
 							sizeof(struct data_urb);
 				kfree(pdata_urb);
-				pdata_urb = NULL;
 				m++;
 			}
 		}
@@ -940,7 +932,7 @@
 		return -EFAULT;
 	}
 /*---------------------------------------------------------------------------*/
-	kd = isdongle(peasycap);
+	kd = easycap_isdongle(peasycap);
 	if (0 <= kd && DONGLE_MANY > kd) {
 		if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) {
 			SAY("ERROR: cannot down dongle[%i].mutex_video\n", kd);
@@ -952,7 +944,7 @@
 	 *  peasycap, IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
 	 *  IF NECESSARY, BAIL OUT.
 	 */
-		if (kd != isdongle(peasycap)) {
+		if (kd != easycap_isdongle(peasycap)) {
 			mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
 			return -ERESTARTSYS;
 		}
@@ -980,21 +972,21 @@
 	*/
 		return -ERESTARTSYS;
 /*---------------------------------------------------------------------------*/
-	rc = easycap_dqbuf(peasycap, 0);
+	rc = easycap_video_dqbuf(peasycap, 0);
 	peasycap->polled = 1;
 	mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
-	if (0 == rc)
-		return POLLIN | POLLRDNORM;
-	else
+	if (rc)
 		return POLLERR;
-	}
+
+	return POLLIN | POLLRDNORM;
+}
 /*****************************************************************************/
 /*---------------------------------------------------------------------------*/
 /*
  *  IF mode IS NONZERO THIS ROUTINE RETURNS -EAGAIN RATHER THAN BLOCKING.
  */
 /*---------------------------------------------------------------------------*/
-int easycap_dqbuf(struct easycap *peasycap, int mode)
+int easycap_video_dqbuf(struct easycap *peasycap, int mode)
 {
 	int input, ifield, miss, rc;
 
@@ -1080,7 +1072,7 @@
 					JOM(8, " ... failed  returning -EIO\n");
 					peasycap->video_eof = 1;
 					peasycap->audio_eof = 1;
-					kill_video_urbs(peasycap);
+					easycap_video_kill_urbs(peasycap);
 					return -EIO;
 				}
 				peasycap->status = 0;
@@ -1090,7 +1082,7 @@
 			#endif /*PERSEVERE*/
 			peasycap->video_eof = 1;
 			peasycap->audio_eof = 1;
-			kill_video_urbs(peasycap);
+			easycap_video_kill_urbs(peasycap);
 			JOM(8, "returning -EIO\n");
 			return -EIO;
 		}
@@ -1143,7 +1135,7 @@
 					JOM(8, " ... failed returning -EIO\n");
 					peasycap->video_eof = 1;
 					peasycap->audio_eof = 1;
-					kill_video_urbs(peasycap);
+					easycap_video_kill_urbs(peasycap);
 					return -EIO;
 				}
 				peasycap->status = 0;
@@ -1153,7 +1145,7 @@
 #endif /*PERSEVERE*/
 			peasycap->video_eof = 1;
 			peasycap->audio_eof = 1;
-			kill_video_urbs(peasycap);
+			easycap_video_kill_urbs(peasycap);
 			JOM(8, "returning -EIO\n");
 			return -EIO;
 		}
@@ -1207,12 +1199,9 @@
  *  WHEN BOOLEAN PARAMETER decimatepixel IS true, ONLY THE FIELD FOR WHICH
  *  odd==false IS TRANSFERRED TO THE FRAME BUFFER.
  *
- *  THE BOOLEAN PARAMETER offerfields IS true ONLY WHEN THE USER PROGRAM
- *  CHOOSES THE OPTION V4L2_FIELD_INTERLACED.
  */
 /*---------------------------------------------------------------------------*/
-int
-field2frame(struct easycap *peasycap)
+static int field2frame(struct easycap *peasycap)
 {
 
 	void *pex, *pad;
@@ -1221,7 +1210,7 @@
 	int rc, bytesperpixel, multiplier;
 	int  much, more, over, rump, caches, input;
 	u8 mask, margin;
-	bool odd, isuy, decimatepixel, offerfields, badinput;
+	bool odd, isuy, decimatepixel, badinput;
 
 	if (!peasycap) {
 		SAY("ERROR: peasycap is NULL\n");
@@ -1237,8 +1226,6 @@
 			peasycap->field_buffer[peasycap->field_read][0].input,
 			peasycap->field_read, peasycap->frame_fill);
 	JOM(8, "=====  %i=bytesperpixel\n", peasycap->bytesperpixel);
-	if (peasycap->offerfields)
-		JOM(8, "===== offerfields\n");
 
 /*---------------------------------------------------------------------------*/
 /*
@@ -1260,7 +1247,6 @@
 #endif /*EASYCAP_TESTCARD*/
 /*---------------------------------------------------------------------------*/
 
-	offerfields = peasycap->offerfields;
 	bytesperpixel = peasycap->bytesperpixel;
 	decimatepixel = peasycap->decimatepixel;
 
@@ -1601,9 +1587,9 @@
  *  REDUCE CODE LENGTH WILL GENERALLY IMPAIR RUNTIME PERFORMANCE.  BEWARE.
  */
 /*---------------------------------------------------------------------------*/
-int
-redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more,
-					u8 mask, u8 margin, bool isuy)
+static int redaub(struct easycap *peasycap,
+		void *pad, void *pex, int much, int more,
+		u8 mask, u8 margin, bool isuy)
 {
 	static s32 ay[256], bu[256], rv[256], gu[256], gv[256];
 	u8 *pcache;
@@ -2855,20 +2841,7 @@
 	}
 	return;
 }
-static const struct file_operations easycap_fops = {
-	.owner		= THIS_MODULE,
-	.open		= easycap_open,
-	.unlocked_ioctl	= easycap_unlocked_ioctl,
-	.poll		= easycap_poll,
-	.mmap		= easycap_mmap,
-	.llseek		= no_llseek,
-};
-static const struct usb_class_driver easycap_class = {
-	.name = "usb/easycap%d",
-	.fops = &easycap_fops,
-	.minor_base = USB_SKEL_MINOR_BASE,
-};
-/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+
 static const struct v4l2_file_operations v4l2_fops = {
 	.owner		= THIS_MODULE,
 	.open		= easycap_open_noinode,
@@ -2917,6 +2890,7 @@
 		SAY("ERROR: usb_host_interface not found\n");
 		return -EFAULT;
 	}
+
 	interface = &alt->desc;
 	if (!interface) {
 		SAY("ERROR: intf_descriptor is NULL\n");
@@ -2976,44 +2950,31 @@
 		if (mutex_lock_interruptible(&mutex_dongle)) {
 			SAY("ERROR: cannot down mutex_dongle\n");
 			return -ERESTARTSYS;
-		} else {
-/*---------------------------------------------------------------------------*/
-		/*
-		 *  FOR INTERFACES 1 AND 2 THE POINTER peasycap WILL NEED TO
-		 *  TO BE THE SAME AS THAT ALLOCATED NOW FOR INTERFACE 0.
-		 *
-		 *  NORMALLY ndong WILL NOT HAVE CHANGED SINCE INTERFACE 0 WAS
-		 *  PROBED, BUT THIS MAY NOT BE THE CASE IF, FOR EXAMPLE, TWO
-		 *  EASYCAPs ARE PLUGGED IN SIMULTANEOUSLY.
-		*/
-/*---------------------------------------------------------------------------*/
-			for (ndong = 0; ndong < DONGLE_MANY; ndong++) {
-				if ((!easycapdc60_dongle[ndong].peasycap) &&
-						(!mutex_is_locked(&easycapdc60_dongle
-							[ndong].mutex_video)) &&
-						(!mutex_is_locked(&easycapdc60_dongle
-							[ndong].mutex_audio))) {
-					easycapdc60_dongle[ndong].peasycap = peasycap;
-					peasycap->isdongle = ndong;
-					JOM(8, "intf[%i]: peasycap-->easycap"
-							"_dongle[%i].peasycap\n",
-							bInterfaceNumber, ndong);
-					break;
-				}
-			}
-			if (DONGLE_MANY <= ndong) {
-				SAM("ERROR: too many dongles\n");
-				mutex_unlock(&mutex_dongle);
-				return -ENOMEM;
-			}
-			mutex_unlock(&mutex_dongle);
 		}
+
+		for (ndong = 0; ndong < DONGLE_MANY; ndong++) {
+			if ((!easycapdc60_dongle[ndong].peasycap) &&
+					(!mutex_is_locked(&easycapdc60_dongle
+						[ndong].mutex_video)) &&
+					(!mutex_is_locked(&easycapdc60_dongle
+						[ndong].mutex_audio))) {
+				easycapdc60_dongle[ndong].peasycap = peasycap;
+				peasycap->isdongle = ndong;
+				JOM(8, "intf[%i]: peasycap-->easycap"
+						"_dongle[%i].peasycap\n",
+						bInterfaceNumber, ndong);
+				break;
+			}
+		}
+
+		if (DONGLE_MANY <= ndong) {
+			SAM("ERROR: too many dongles\n");
+			mutex_unlock(&mutex_dongle);
+			return -ENOMEM;
+		}
+		mutex_unlock(&mutex_dongle);
+
 		peasycap->allocation_video_struct = sizeof(struct easycap);
-		peasycap->allocation_video_page = 0;
-		peasycap->allocation_video_urb = 0;
-		peasycap->allocation_audio_struct = 0;
-		peasycap->allocation_audio_page = 0;
-		peasycap->allocation_audio_urb = 0;
 
 /*---------------------------------------------------------------------------*/
 /*
@@ -3023,7 +2984,6 @@
 		peasycap->pusb_device = usbdev;
 		peasycap->pusb_interface = intf;
 
-		peasycap->ilk = 0;
 		peasycap->microphone = false;
 
 		peasycap->video_interface = -1;
@@ -3042,38 +3002,21 @@
 
 		peasycap->frame_buffer_many = FRAME_BUFFER_MANY;
 
-		for (k = 0; k < INPUT_MANY; k++)
-			peasycap->lost[k] = 0;
-		peasycap->skip = 0;
-		peasycap->skipped = 0;
-		peasycap->offerfields = 0;
 /*---------------------------------------------------------------------------*/
 /*
  *  DYNAMICALLY FILL IN THE AVAILABLE FORMATS ...
  */
 /*---------------------------------------------------------------------------*/
-		rc = fillin_formats();
+		rc = easycap_video_fillin_formats();
 		if (0 > rc) {
 			SAM("ERROR: fillin_formats() rc = %i\n", rc);
 			return -EFAULT;
 		}
 		JOM(4, "%i formats available\n", rc);
-/*---------------------------------------------------------------------------*/
-/*
- *  ... AND POPULATE easycap.inputset[]
-*/
-/*---------------------------------------------------------------------------*/
-		/* FIXME: maybe we just use memset 0 */
+
+		/*  ... AND POPULATE easycap.inputset[] */
+
 		inputset = peasycap->inputset;
-		for (k = 0; k < INPUT_MANY; k++) {
-			inputset[k].input_ok = 0;
-			inputset[k].standard_offset_ok = 0;
-			inputset[k].format_offset_ok = 0;
-			inputset[k].brightness_ok = 0;
-			inputset[k].contrast_ok = 0;
-			inputset[k].saturation_ok = 0;
-			inputset[k].hue_ok = 0;
-		}
 
 		fmtidx = peasycap->ntsc ? NTSC_M : PAL_BGHIN;
 		m = 0;
@@ -3390,11 +3333,10 @@
 		if (!isokalt) {
 			SAM("ERROR:  no viable video_altsetting_on\n");
 			return -ENOENT;
-		} else {
-			peasycap->video_altsetting_on = okalt[isokalt - 1];
-			JOM(4, "%i=video_altsetting_on <====\n",
-						peasycap->video_altsetting_on);
 		}
+		peasycap->video_altsetting_on = okalt[isokalt - 1];
+		JOM(4, "%i=video_altsetting_on <====\n",
+					peasycap->video_altsetting_on);
 /*---------------------------------------------------------------------------*/
 /*
  *  DECIDE THE VIDEO STREAMING PARAMETERS
@@ -3480,8 +3422,9 @@
 						SAM("ERROR: Could not allocate frame "
 							"buffer %i page %i\n", k, m);
 						return -ENOMEM;
-					} else
-						peasycap->allocation_video_page += 1;
+					}
+
+					peasycap->allocation_video_page += 1;
 					peasycap->frame_buffer[k][m].pgo = pbuf;
 				}
 				peasycap->frame_buffer[k][m].pto =
@@ -3510,11 +3453,11 @@
 						SAM("ERROR: Could not allocate field"
 							" buffer %i page %i\n", k, m);
 						return -ENOMEM;
-						}
-					else
-						peasycap->allocation_video_page += 1;
-					peasycap->field_buffer[k][m].pgo = pbuf;
 					}
+
+					peasycap->allocation_video_page += 1;
+					peasycap->field_buffer[k][m].pgo = pbuf;
+				}
 				peasycap->field_buffer[k][m].pto =
 						peasycap->field_buffer[k][m].pgo;
 			}
@@ -3538,9 +3481,9 @@
 				SAM("ERROR: Could not allocate isoc video buffer "
 									"%i\n", k);
 				return -ENOMEM;
-			} else
-				peasycap->allocation_video_page +=
-					BIT(VIDEO_ISOC_ORDER);
+			}
+			peasycap->allocation_video_page +=
+						BIT(VIDEO_ISOC_ORDER);
 
 			peasycap->video_isoc_buffer[k].pgo = pbuf;
 			peasycap->video_isoc_buffer[k].pto =
@@ -3569,15 +3512,17 @@
 				SAM("ERROR: usb_alloc_urb returned NULL for buffer "
 									"%i\n", k);
 				return -ENOMEM;
-			} else
-				peasycap->allocation_video_urb += 1;
+			}
+
+			peasycap->allocation_video_urb += 1;
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 			pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
 			if (!pdata_urb) {
 				SAM("ERROR: Could not allocate struct data_urb.\n");
 				return -ENOMEM;
-			} else
-				peasycap->allocation_video_struct +=
+			}
+
+			peasycap->allocation_video_struct +=
 							sizeof(struct data_urb);
 
 			pdata_urb->purb = purb;
@@ -3694,13 +3639,12 @@
 			err("Not able to register with videodev");
 			videodev_release(&(peasycap->video_device));
 			return -ENODEV;
-		} else {
-			(peasycap->registered_video)++;
-			SAM("registered with videodev: %i=minor\n",
-							peasycap->video_device.minor);
-			peasycap->minor = peasycap->video_device.minor;
 		}
-/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+
+		peasycap->registered_video++;
+		SAM("registered with videodev: %i=minor\n",
+						peasycap->video_device.minor);
+		peasycap->minor = peasycap->video_device.minor;
 
 		break;
 	}
@@ -3734,11 +3678,10 @@
 		if (!isokalt) {
 			SAM("ERROR:  no viable audio_altsetting_on\n");
 			return -ENOENT;
-		} else {
-			peasycap->audio_altsetting_on = okalt[isokalt - 1];
-			JOM(4, "%i=audio_altsetting_on <====\n",
-							peasycap->audio_altsetting_on);
 		}
+		peasycap->audio_altsetting_on = okalt[isokalt - 1];
+		JOM(4, "%i=audio_altsetting_on <====\n",
+						peasycap->audio_altsetting_on);
 
 		peasycap->audio_endpointnumber = okepn[isokalt - 1];
 		JOM(4, "%i=audio_endpointnumber\n", peasycap->audio_endpointnumber);
@@ -3847,8 +3790,8 @@
 				SAM("ERROR: Could not allocate isoc audio buffer "
 								"%i\n", k);
 				return -ENOMEM;
-			} else
-				peasycap->allocation_audio_page +=
+			}
+			peasycap->allocation_audio_page +=
 						BIT(AUDIO_ISOC_ORDER);
 
 			peasycap->audio_isoc_buffer[k].pgo = pbuf;
@@ -3996,12 +3939,9 @@
 {
 	struct usb_host_interface *pusb_host_interface;
 	struct usb_interface_descriptor *pusb_interface_descriptor;
-	u8 bInterfaceNumber;
 	struct easycap *peasycap;
-
-	struct list_head *plist_head;
-	struct data_urb *pdata_urb;
-	int minor, m, kd;
+	int minor, kd;
+	u8 bInterfaceNumber;
 
 	JOT(4, "\n");
 
@@ -4036,45 +3976,14 @@
 	peasycap->audio_eof = 1;
 	wake_up_interruptible(&(peasycap->wq_video));
 	wake_up_interruptible(&(peasycap->wq_audio));
-/*---------------------------------------------------------------------------*/
+
 	switch (bInterfaceNumber) {
-	case 0: {
-		if (peasycap->purb_video_head) {
-			JOM(4, "killing video urbs\n");
-			m = 0;
-			list_for_each(plist_head, peasycap->purb_video_head) {
-				pdata_urb = list_entry(plist_head,
-						struct data_urb, list_head);
-				if (pdata_urb) {
-					if (pdata_urb->purb) {
-						usb_kill_urb(pdata_urb->purb);
-						m++;
-					}
-				}
-			}
-			JOM(4, "%i video urbs killed\n", m);
-		}
+	case 0:
+		easycap_video_kill_urbs(peasycap);
 		break;
-	}
-/*---------------------------------------------------------------------------*/
-	case 2: {
-		if (peasycap->purb_audio_head) {
-			JOM(4, "killing audio urbs\n");
-			m = 0;
-			list_for_each(plist_head, peasycap->purb_audio_head) {
-				pdata_urb = list_entry(plist_head,
-						struct data_urb, list_head);
-				if (pdata_urb) {
-					if (pdata_urb->purb) {
-						usb_kill_urb(pdata_urb->purb);
-						m++;
-					}
-				}
-			}
-			JOM(4, "%i audio urbs killed\n", m);
-		}
+	case 2:
+		easycap_audio_kill_urbs(peasycap);
 		break;
-	}
 	default:
 		break;
 	}
@@ -4087,7 +3996,7 @@
  *  AN EasyCAP IS UNPLUGGED WHILE THE URBS ARE RUNNING.  BEWARE.
  */
 /*--------------------------------------------------------------------------*/
-	kd = isdongle(peasycap);
+	kd = easycap_isdongle(peasycap);
 	switch (bInterfaceNumber) {
 	case 0: {
 		if (0 <= kd && DONGLE_MANY > kd) {
@@ -4212,7 +4121,7 @@
 };
 
 MODULE_DEVICE_TABLE(usb, easycap_usb_device_id_table);
-struct usb_driver easycap_usb_driver = {
+static struct usb_driver easycap_usb_driver = {
 	.name = "easycap",
 	.id_table = easycap_usb_device_id_table,
 	.probe = easycap_usb_probe,
diff --git a/drivers/staging/media/easycap/easycap_settings.c b/drivers/staging/media/easycap/easycap_settings.c
index 70f59b1..3f5f5b3 100644
--- a/drivers/staging/media/easycap/easycap_settings.c
+++ b/drivers/staging/media/easycap/easycap_settings.c
@@ -313,7 +313,7 @@
 
 struct easycap_format easycap_format[1 + SETTINGS_MANY];
 
-int fillin_formats(void)
+int easycap_video_fillin_formats(void)
 {
 	const char *name1, *name2, *name3, *name4;
 	struct v4l2_format *fmt;
diff --git a/drivers/staging/media/easycap/easycap_sound.c b/drivers/staging/media/easycap/easycap_sound.c
index b22bb39..8c8bcae 100644
--- a/drivers/staging/media/easycap/easycap_sound.c
+++ b/drivers/staging/media/easycap/easycap_sound.c
@@ -56,6 +56,141 @@
 };
 
 
+/*---------------------------------------------------------------------------*/
+/*
+ *  SUBMIT ALL AUDIO URBS.
+ */
+/*---------------------------------------------------------------------------*/
+static int easycap_audio_submit_urbs(struct easycap *peasycap)
+{
+	struct data_urb *pdata_urb;
+	struct urb *purb;
+	struct list_head *plist_head;
+	int j, isbad, nospc, m, rc;
+	int isbuf;
+
+	if (!peasycap->purb_audio_head) {
+		SAM("ERROR: peasycap->urb_audio_head uninitialized\n");
+		return -EFAULT;
+	}
+	if (!peasycap->pusb_device) {
+		SAM("ERROR: peasycap->pusb_device is NULL\n");
+		return -EFAULT;
+	}
+
+	if (peasycap->audio_isoc_streaming) {
+		JOM(4, "already streaming audio urbs\n");
+		return 0;
+	}
+
+	JOM(4, "initial submission of all audio urbs\n");
+	rc = usb_set_interface(peasycap->pusb_device,
+			       peasycap->audio_interface,
+			       peasycap->audio_altsetting_on);
+	JOM(8, "usb_set_interface(.,%i,%i) returned %i\n",
+	    peasycap->audio_interface,
+	    peasycap->audio_altsetting_on, rc);
+
+	isbad = 0;
+	nospc = 0;
+	m = 0;
+	list_for_each(plist_head, peasycap->purb_audio_head) {
+		pdata_urb = list_entry(plist_head, struct data_urb, list_head);
+		if (pdata_urb && pdata_urb->purb) {
+			purb = pdata_urb->purb;
+			isbuf = pdata_urb->isbuf;
+
+			purb->interval = 1;
+			purb->dev = peasycap->pusb_device;
+			purb->pipe = usb_rcvisocpipe(peasycap->pusb_device,
+					peasycap->audio_endpointnumber);
+			purb->transfer_flags = URB_ISO_ASAP;
+			purb->transfer_buffer = peasycap->audio_isoc_buffer[isbuf].pgo;
+			purb->transfer_buffer_length = peasycap->audio_isoc_buffer_size;
+			purb->complete = easycap_alsa_complete;
+			purb->context = peasycap;
+			purb->start_frame = 0;
+			purb->number_of_packets = peasycap->audio_isoc_framesperdesc;
+			for (j = 0;  j < peasycap->audio_isoc_framesperdesc; j++) {
+				purb->iso_frame_desc[j].offset = j * peasycap->audio_isoc_maxframesize;
+				purb->iso_frame_desc[j].length = peasycap->audio_isoc_maxframesize;
+			}
+
+			rc = usb_submit_urb(purb, GFP_KERNEL);
+			if (rc) {
+				isbad++;
+				SAM("ERROR: usb_submit_urb() failed"
+				    " for urb with rc: -%s: %d\n",
+				    strerror(rc), rc);
+			} else {
+				m++;
+			}
+		} else {
+			isbad++;
+		}
+	}
+	if (nospc) {
+		SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc);
+		SAM(".....  possibly inadequate USB bandwidth\n");
+		peasycap->audio_eof = 1;
+	}
+
+	if (isbad)
+		easycap_audio_kill_urbs(peasycap);
+	else
+		peasycap->audio_isoc_streaming = m;
+
+	return 0;
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  COMMON AUDIO INITIALIZATION
+ */
+/*---------------------------------------------------------------------------*/
+static int easycap_sound_setup(struct easycap *peasycap)
+{
+	int rc;
+
+	JOM(4, "starting initialization\n");
+
+	if (!peasycap) {
+		SAY("ERROR:  peasycap is NULL.\n");
+		return -EFAULT;
+	}
+	if (!peasycap->pusb_device) {
+		SAM("ERROR: peasycap->pusb_device is NULL\n");
+		return -ENODEV;
+	}
+	JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device);
+
+	rc = easycap_audio_setup(peasycap);
+	JOM(8, "audio_setup() returned %i\n", rc);
+
+	if (!peasycap->pusb_device) {
+		SAM("ERROR: peasycap->pusb_device has become NULL\n");
+		return -ENODEV;
+	}
+/*---------------------------------------------------------------------------*/
+	if (!peasycap->pusb_device) {
+		SAM("ERROR: peasycap->pusb_device has become NULL\n");
+		return -ENODEV;
+	}
+	rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface,
+			       peasycap->audio_altsetting_on);
+	JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface,
+	    peasycap->audio_altsetting_on, rc);
+
+	rc = easycap_wakeup_device(peasycap->pusb_device);
+	JOM(8, "wakeup_device() returned %i\n", rc);
+
+	peasycap->audio_eof = 0;
+	peasycap->audio_idle = 0;
+
+	easycap_audio_submit_urbs(peasycap);
+
+	JOM(4, "finished initialization\n");
+	return 0;
+}
 /*****************************************************************************/
 /*---------------------------------------------------------------------------*/
 /*
@@ -64,8 +199,7 @@
  *  IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO.
  */
 /*---------------------------------------------------------------------------*/
-void
-easycap_alsa_complete(struct urb *purb)
+void easycap_alsa_complete(struct urb *purb)
 {
 	struct easycap *peasycap;
 	struct snd_pcm_substream *pss;
@@ -458,7 +592,6 @@
 static int easycap_alsa_trigger(struct snd_pcm_substream *pss, int cmd)
 {
 	struct easycap *peasycap;
-	int retval;
 
 	JOT(4, "%i=cmd cf %i=START %i=STOP\n", cmd, SNDRV_PCM_TRIGGER_START,
 	    SNDRV_PCM_TRIGGER_STOP);
@@ -481,7 +614,7 @@
 		break;
 	}
 	default:
-		retval = -EINVAL;
+		return -EINVAL;
 	}
 	return 0;
 }
@@ -615,202 +748,3 @@
 	return 0;
 }
 
-/*****************************************************************************/
-/*****************************************************************************/
-/*****************************************************************************/
-/*****************************************************************************/
-/*****************************************************************************/
-/*****************************************************************************/
-/*---------------------------------------------------------------------------*/
-/*
- *  COMMON AUDIO INITIALIZATION
- */
-/*---------------------------------------------------------------------------*/
-int
-easycap_sound_setup(struct easycap *peasycap)
-{
-	int rc;
-
-	JOM(4, "starting initialization\n");
-
-	if (!peasycap) {
-		SAY("ERROR:  peasycap is NULL.\n");
-		return -EFAULT;
-	}
-	if (!peasycap->pusb_device) {
-		SAM("ERROR: peasycap->pusb_device is NULL\n");
-		return -ENODEV;
-	}
-	JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device);
-
-	rc = audio_setup(peasycap);
-	JOM(8, "audio_setup() returned %i\n", rc);
-
-	if (!peasycap->pusb_device) {
-		SAM("ERROR: peasycap->pusb_device has become NULL\n");
-		return -ENODEV;
-	}
-/*---------------------------------------------------------------------------*/
-	if (!peasycap->pusb_device) {
-		SAM("ERROR: peasycap->pusb_device has become NULL\n");
-		return -ENODEV;
-	}
-	rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface,
-			       peasycap->audio_altsetting_on);
-	JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface,
-	    peasycap->audio_altsetting_on, rc);
-
-	rc = wakeup_device(peasycap->pusb_device);
-	JOM(8, "wakeup_device() returned %i\n", rc);
-
-	peasycap->audio_eof = 0;
-	peasycap->audio_idle = 0;
-
-	submit_audio_urbs(peasycap);
-
-	JOM(4, "finished initialization\n");
-	return 0;
-}
-/*****************************************************************************/
-/*---------------------------------------------------------------------------*/
-/*
- *  SUBMIT ALL AUDIO URBS.
- */
-/*---------------------------------------------------------------------------*/
-int
-submit_audio_urbs(struct easycap *peasycap)
-{
-	struct data_urb *pdata_urb;
-	struct urb *purb;
-	struct list_head *plist_head;
-	int j, isbad, nospc, m, rc;
-	int isbuf;
-
-	if (!peasycap) {
-		SAY("ERROR: peasycap is NULL\n");
-		return -EFAULT;
-	}
-	if (!peasycap->purb_audio_head) {
-		SAM("ERROR: peasycap->urb_audio_head uninitialized\n");
-		return -EFAULT;
-	}
-	if (!peasycap->pusb_device) {
-		SAM("ERROR: peasycap->pusb_device is NULL\n");
-		return -EFAULT;
-	}
-
-	if (peasycap->audio_isoc_streaming) {
-		JOM(4, "already streaming audio urbs\n");
-		return 0;
-	}
-
-	JOM(4, "initial submission of all audio urbs\n");
-	rc = usb_set_interface(peasycap->pusb_device,
-			       peasycap->audio_interface,
-			       peasycap->audio_altsetting_on);
-	JOM(8, "usb_set_interface(.,%i,%i) returned %i\n",
-	    peasycap->audio_interface,
-	    peasycap->audio_altsetting_on, rc);
-
-	isbad = 0;
-	nospc = 0;
-	m = 0;
-	list_for_each(plist_head, peasycap->purb_audio_head) {
-		pdata_urb = list_entry(plist_head, struct data_urb, list_head);
-		if (pdata_urb && pdata_urb->purb) {
-			purb = pdata_urb->purb;
-			isbuf = pdata_urb->isbuf;
-
-			purb->interval = 1;
-			purb->dev = peasycap->pusb_device;
-			purb->pipe = usb_rcvisocpipe(peasycap->pusb_device,
-					peasycap->audio_endpointnumber);
-			purb->transfer_flags = URB_ISO_ASAP;
-			purb->transfer_buffer = peasycap->audio_isoc_buffer[isbuf].pgo;
-			purb->transfer_buffer_length = peasycap->audio_isoc_buffer_size;
-			purb->complete = easycap_alsa_complete;
-			purb->context = peasycap;
-			purb->start_frame = 0;
-			purb->number_of_packets = peasycap->audio_isoc_framesperdesc;
-			for (j = 0;  j < peasycap->audio_isoc_framesperdesc; j++) {
-				purb->iso_frame_desc[j].offset = j * peasycap->audio_isoc_maxframesize;
-				purb->iso_frame_desc[j].length = peasycap->audio_isoc_maxframesize;
-			}
-
-			rc = usb_submit_urb(purb, GFP_KERNEL);
-			if (rc) {
-				isbad++;
-				SAM("ERROR: usb_submit_urb() failed"
-				    " for urb with rc: -%s: %d\n",
-				    strerror(rc), rc);
-			} else {
-				m++;
-			}
-		} else {
-			isbad++;
-		}
-	}
-	if (nospc) {
-		SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc);
-		SAM(".....  possibly inadequate USB bandwidth\n");
-		peasycap->audio_eof = 1;
-	}
-	if (isbad) {
-		JOM(4, "attempting cleanup instead of submitting\n");
-		list_for_each(plist_head, (peasycap->purb_audio_head)) {
-			pdata_urb = list_entry(plist_head, struct data_urb, list_head);
-			if (pdata_urb && pdata_urb->purb)
-				usb_kill_urb(pdata_urb->purb);
-		}
-		peasycap->audio_isoc_streaming = 0;
-	} else {
-		peasycap->audio_isoc_streaming = m;
-		JOM(4, "submitted %i audio urbs\n", m);
-	}
-
-	return 0;
-}
-/*****************************************************************************/
-/*---------------------------------------------------------------------------*/
-/*
- *  KILL ALL AUDIO URBS.
- */
-/*---------------------------------------------------------------------------*/
-int
-kill_audio_urbs(struct easycap *peasycap)
-{
-	int m;
-	struct list_head *plist_head;
-	struct data_urb *pdata_urb;
-
-	if (!peasycap) {
-		SAY("ERROR: peasycap is NULL\n");
-		return -EFAULT;
-	}
-
-	if (!peasycap->audio_isoc_streaming) {
-		JOM(8, "%i=audio_isoc_streaming, no audio urbs killed\n",
-		    peasycap->audio_isoc_streaming);
-		return 0;
-	}
-
-	if (!peasycap->purb_audio_head) {
-		SAM("ERROR: peasycap->purb_audio_head is NULL\n");
-		return -EFAULT;
-	}
-
-	peasycap->audio_isoc_streaming = 0;
-	JOM(4, "killing audio urbs\n");
-	m = 0;
-	list_for_each(plist_head, (peasycap->purb_audio_head)) {
-		pdata_urb = list_entry(plist_head, struct data_urb, list_head);
-		if (pdata_urb && pdata_urb->purb) {
-			usb_kill_urb(pdata_urb->purb);
-			m++;
-		}
-	}
-	JOM(4, "%i audio urbs killed\n", m);
-
-	return 0;
-}
-/*****************************************************************************/
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
index 3db3b0a..cffb0b3 100644
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
@@ -1054,7 +1054,13 @@
 	else
 		go->hpi_ops = &go7007_usb_onboard_hpi_ops;
 	go->hpi_context = usb;
-	usb_fill_int_urb(usb->intr_urb, usb->usbdev,
+	if (go->board_id == GO7007_BOARDID_SENSORAY_2250)
+		usb_fill_bulk_urb(usb->intr_urb, usb->usbdev,
+			usb_rcvbulkpipe(usb->usbdev, 4),
+			usb->intr_urb->transfer_buffer, 2*sizeof(u16),
+			go7007_usb_readinterrupt_complete, go);
+	else
+		usb_fill_int_urb(usb->intr_urb, usb->usbdev,
 			usb_rcvintpipe(usb->usbdev, 4),
 			usb->intr_urb->transfer_buffer, 2*sizeof(u16),
 			go7007_usb_readinterrupt_complete, go, 8);
diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c
index f5308d5..c1654b1 100644
--- a/drivers/staging/media/lirc/lirc_imon.c
+++ b/drivers/staging/media/lirc/lirc_imon.c
@@ -63,7 +63,7 @@
 static int display_close(struct inode *inode, struct file *file);
 
 /* VFD write operation */
-static ssize_t vfd_write(struct file *file, const char *buf,
+static ssize_t vfd_write(struct file *file, const char __user *buf,
 			 size_t n_bytes, loff_t *pos);
 
 /* LIRC driver function prototypes */
@@ -369,7 +369,7 @@
  * than 32 bytes are provided spaces will be appended to
  * generate a full screen.
  */
-static ssize_t vfd_write(struct file *file, const char *buf,
+static ssize_t vfd_write(struct file *file, const char __user *buf,
 			 size_t n_bytes, loff_t *pos)
 {
 	int i;
diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
index 8a060a8..0ca308a 100644
--- a/drivers/staging/media/lirc/lirc_serial.c
+++ b/drivers/staging/media/lirc/lirc_serial.c
@@ -773,7 +773,7 @@
 		/* we fail, there's nothing here */
 		printk(KERN_ERR LIRC_DRIVER_NAME ": port existence test "
 		       "failed, cannot continue\n");
-		return -EINVAL;
+		return -ENODEV;
 	}
 
 
@@ -836,25 +836,22 @@
 	return 0;
 }
 
-static int init_port(void)
+static int __devinit lirc_serial_probe(struct platform_device *dev)
 {
 	int i, nlow, nhigh, result;
 
 	result = request_irq(irq, irq_handler,
 			     (share_irq ? IRQF_SHARED : 0),
 			     LIRC_DRIVER_NAME, (void *)&hardware);
-
-	switch (result) {
-	case -EBUSY:
-		printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq);
-		return -EBUSY;
-	case -EINVAL:
-		printk(KERN_ERR LIRC_DRIVER_NAME
-		       ": Bad irq number or handler\n");
-		return -EINVAL;
-	default:
-		break;
-	};
+	if (result < 0) {
+		if (result == -EBUSY)
+			printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n",
+			       irq);
+		else if (result == -EINVAL)
+			printk(KERN_ERR LIRC_DRIVER_NAME
+			       ": Bad irq number or handler\n");
+		return result;
+	}
 
 	/* Reserve io region. */
 	/*
@@ -875,11 +872,13 @@
 		       ": or compile the serial port driver as module and\n");
 		printk(KERN_WARNING LIRC_DRIVER_NAME
 		       ": make sure this module is loaded first\n");
-		return -EBUSY;
+		result = -EBUSY;
+		goto exit_free_irq;
 	}
 
-	if (hardware_init_port() < 0)
-		return -EINVAL;
+	result = hardware_init_port();
+	if (result < 0)
+		goto exit_release_region;
 
 	/* Initialize pulse/space widths */
 	init_timing_params(duty_cycle, freq);
@@ -911,6 +910,28 @@
 
 	dprintk("Interrupt %d, port %04x obtained\n", irq, io);
 	return 0;
+
+exit_release_region:
+	if (iommap != 0)
+		release_mem_region(iommap, 8 << ioshift);
+	else
+		release_region(io, 8);
+exit_free_irq:
+	free_irq(irq, (void *)&hardware);
+
+	return result;
+}
+
+static int __devexit lirc_serial_remove(struct platform_device *dev)
+{
+	free_irq(irq, (void *)&hardware);
+
+	if (iommap != 0)
+		release_mem_region(iommap, 8 << ioshift);
+	else
+		release_region(io, 8);
+
+	return 0;
 }
 
 static int set_use_inc(void *data)
@@ -955,7 +976,7 @@
 	int *wbuf;
 
 	if (!(hardware[type].features & LIRC_CAN_SEND_PULSE))
-		return -EBADF;
+		return -EPERM;
 
 	count = n / sizeof(int);
 	if (n % sizeof(int) || count % 2 == 0)
@@ -1006,11 +1027,11 @@
 			return result;
 		/* only LIRC_MODE_PULSE supported */
 		if (value != LIRC_MODE_PULSE)
-			return -ENOSYS;
+			return -EINVAL;
 		break;
 
 	case LIRC_GET_LENGTH:
-		return -ENOSYS;
+		return -ENOIOCTLCMD;
 		break;
 
 	case LIRC_SET_SEND_DUTY_CYCLE:
@@ -1076,16 +1097,6 @@
 
 static struct platform_device *lirc_serial_dev;
 
-static int __devinit lirc_serial_probe(struct platform_device *dev)
-{
-	return 0;
-}
-
-static int __devexit lirc_serial_remove(struct platform_device *dev)
-{
-	return 0;
-}
-
 static int lirc_serial_suspend(struct platform_device *dev,
 			       pm_message_t state)
 {
@@ -1111,11 +1122,11 @@
 static int lirc_serial_resume(struct platform_device *dev)
 {
 	unsigned long flags;
+	int result;
 
-	if (hardware_init_port() < 0) {
-		lirc_serial_exit();
-		return -EINVAL;
-	}
+	result = hardware_init_port();
+	if (result < 0)
+		return result;
 
 	spin_lock_irqsave(&hardware[type].lock, flags);
 	/* Enable Interrupt */
@@ -1148,7 +1159,7 @@
 	/* Init read buffer. */
 	result = lirc_buffer_init(&rbuf, sizeof(int), RBUF_LEN);
 	if (result < 0)
-		return -ENOMEM;
+		return result;
 
 	result = platform_driver_register(&lirc_serial_driver);
 	if (result) {
@@ -1188,10 +1199,6 @@
 {
 	int result;
 
-	result = lirc_serial_init();
-	if (result)
-		return result;
-
 	switch (type) {
 	case LIRC_HOMEBREW:
 	case LIRC_IRDEO:
@@ -1211,8 +1218,7 @@
 		break;
 #endif
 	default:
-		result = -EINVAL;
-		goto exit_serial_exit;
+		return -EINVAL;
 	}
 	if (!softcarrier) {
 		switch (type) {
@@ -1228,37 +1234,26 @@
 		}
 	}
 
-	result = init_port();
-	if (result < 0)
-		goto exit_serial_exit;
+	result = lirc_serial_init();
+	if (result)
+		return result;
+
 	driver.features = hardware[type].features;
 	driver.dev = &lirc_serial_dev->dev;
 	driver.minor = lirc_register_driver(&driver);
 	if (driver.minor < 0) {
 		printk(KERN_ERR  LIRC_DRIVER_NAME
 		       ": register_chrdev failed!\n");
-		result = -EIO;
-		goto exit_release;
+		lirc_serial_exit();
+		return driver.minor;
 	}
 	return 0;
-exit_release:
-	release_region(io, 8);
-exit_serial_exit:
-	lirc_serial_exit();
-	return result;
 }
 
 static void __exit lirc_serial_exit_module(void)
 {
-	lirc_serial_exit();
-
-	free_irq(irq, (void *)&hardware);
-
-	if (iommap != 0)
-		release_mem_region(iommap, 8 << ioshift);
-	else
-		release_region(io, 8);
 	lirc_unregister_driver(driver.minor);
+	lirc_serial_exit();
 	dprintk("cleaned up module\n");
 }
 
diff --git a/drivers/staging/media/solo6x10/Makefile b/drivers/staging/media/solo6x10/Makefile
index 72816cf..337e38c 100644
--- a/drivers/staging/media/solo6x10/Makefile
+++ b/drivers/staging/media/solo6x10/Makefile
@@ -1,3 +1,3 @@
 solo6x10-y := core.o i2c.o p2m.o v4l2.o tw28.o gpio.o disp.o enc.o v4l2-enc.o g723.o
 
-obj-$(CONFIG_SOLO6X10) := solo6x10.o
+obj-$(CONFIG_SOLO6X10) += solo6x10.o
diff --git a/drivers/staging/media/solo6x10/jpeg.h b/drivers/staging/media/solo6x10/solo6x10-jpeg.h
similarity index 100%
rename from drivers/staging/media/solo6x10/jpeg.h
rename to drivers/staging/media/solo6x10/solo6x10-jpeg.h
diff --git a/drivers/staging/media/solo6x10/v4l2-enc.c b/drivers/staging/media/solo6x10/v4l2-enc.c
index bee7280..f8f0da9 100644
--- a/drivers/staging/media/solo6x10/v4l2-enc.c
+++ b/drivers/staging/media/solo6x10/v4l2-enc.c
@@ -26,7 +26,7 @@
 #include <media/videobuf-dma-sg.h>
 #include "solo6x10.h"
 #include "tw28.h"
-#include "jpeg.h"
+#include "solo6x10-jpeg.h"
 
 #define MIN_VID_BUFFERS		4
 #define FRAME_BUF_SIZE		(128 * 1024)
diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h
index 1b1094c..a3c7623 100644
--- a/include/linux/dvb/frontend.h
+++ b/include/linux/dvb/frontend.h
@@ -316,7 +316,9 @@
 
 #define DTV_DVBT2_PLP_ID	43
 
-#define DTV_MAX_COMMAND				DTV_DVBT2_PLP_ID
+#define DTV_ENUM_DELSYS		44
+
+#define DTV_MAX_COMMAND				DTV_ENUM_DELSYS
 
 typedef enum fe_pilot {
 	PILOT_ON,
@@ -333,7 +335,7 @@
 
 typedef enum fe_delivery_system {
 	SYS_UNDEFINED,
-	SYS_DVBC_ANNEX_AC,
+	SYS_DVBC_ANNEX_A,
 	SYS_DVBC_ANNEX_B,
 	SYS_DVBT,
 	SYS_DSS,
@@ -350,8 +352,13 @@
 	SYS_DAB,
 	SYS_DVBT2,
 	SYS_TURBO,
+	SYS_DVBC_ANNEX_C,
 } fe_delivery_system_t;
 
+
+#define SYS_DVBC_ANNEX_AC	SYS_DVBC_ANNEX_A
+
+
 struct dtv_cmds_h {
 	char	*name;		/* A display name for debugging purposes */
 
diff --git a/include/linux/dvb/version.h b/include/linux/dvb/version.h
index 66594b1..0559e2b 100644
--- a/include/linux/dvb/version.h
+++ b/include/linux/dvb/version.h
@@ -24,6 +24,6 @@
 #define _DVBVERSION_H_
 
 #define DVB_API_VERSION 5
-#define DVB_API_VERSION_MINOR 4
+#define DVB_API_VERSION_MINOR 5
 
 #endif /*_DVBVERSION_H_*/
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 4b752d5..3d62631 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1682,6 +1682,8 @@
 #define V4L2_FLASH_FAULT_TIMEOUT		(1 << 1)
 #define V4L2_FLASH_FAULT_OVER_TEMPERATURE	(1 << 2)
 #define V4L2_FLASH_FAULT_SHORT_CIRCUIT		(1 << 3)
+#define V4L2_FLASH_FAULT_OVER_CURRENT		(1 << 4)
+#define V4L2_FLASH_FAULT_INDICATOR		(1 << 5)
 
 #define V4L2_CID_FLASH_CHARGE			(V4L2_CID_FLASH_CLASS_BASE + 11)
 #define V4L2_CID_FLASH_READY			(V4L2_CID_FLASH_CLASS_BASE + 12)
diff --git a/include/media/as3645a.h b/include/media/as3645a.h
new file mode 100644
index 0000000..5075496
--- /dev/null
+++ b/include/media/as3645a.h
@@ -0,0 +1,71 @@
+/*
+ * include/media/as3645a.h
+ *
+ * Copyright (C) 2008-2011 Nokia Corporation
+ *
+ * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __AS3645A_H__
+#define __AS3645A_H__
+
+#include <media/v4l2-subdev.h>
+
+#define AS3645A_NAME				"as3645a"
+#define AS3645A_I2C_ADDR			(0x60 >> 1) /* W:0x60, R:0x61 */
+
+#define AS3645A_FLASH_TIMEOUT_MIN		100000	/* us */
+#define AS3645A_FLASH_TIMEOUT_MAX		850000
+#define AS3645A_FLASH_TIMEOUT_STEP		50000
+
+#define AS3645A_FLASH_INTENSITY_MIN		200	/* mA */
+#define AS3645A_FLASH_INTENSITY_MAX_1LED	500
+#define AS3645A_FLASH_INTENSITY_MAX_2LEDS	400
+#define AS3645A_FLASH_INTENSITY_STEP		20
+
+#define AS3645A_TORCH_INTENSITY_MIN		20	/* mA */
+#define AS3645A_TORCH_INTENSITY_MAX		160
+#define AS3645A_TORCH_INTENSITY_STEP		20
+
+#define AS3645A_INDICATOR_INTENSITY_MIN		0	/* uA */
+#define AS3645A_INDICATOR_INTENSITY_MAX		10000
+#define AS3645A_INDICATOR_INTENSITY_STEP	2500
+
+/*
+ * as3645a_platform_data - Flash controller platform data
+ * @set_power:	Set power callback
+ * @vref:	VREF offset (0=0V, 1=+0.3V, 2=-0.3V, 3=+0.6V)
+ * @peak:	Inductor peak current limit (0=1.25A, 1=1.5A, 2=1.75A, 3=2.0A)
+ * @ext_strobe:	True if external flash strobe can be used
+ * @flash_max_current:	Max flash current (mA, <= AS3645A_FLASH_INTENSITY_MAX)
+ * @torch_max_current:	Max torch current (mA, >= AS3645A_TORCH_INTENSITY_MAX)
+ * @timeout_max:	Max flash timeout (us, <= AS3645A_FLASH_TIMEOUT_MAX)
+ */
+struct as3645a_platform_data {
+	int (*set_power)(struct v4l2_subdev *subdev, int on);
+	unsigned int vref;
+	unsigned int peak;
+	bool ext_strobe;
+
+	/* Flash and torch currents and timeout limits */
+	unsigned int flash_max_current;
+	unsigned int torch_max_current;
+	unsigned int timeout_max;
+};
+
+#endif /* __AS3645A_H__ */
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index cd8bca6..29e7bba 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -98,7 +98,7 @@
 
 		/* Sub-device specifications */
 		/* Nothing needed yet */
-	};
+	} info;
 };
 
 static inline u32 media_entity_type(struct media_entity *entity)
diff --git a/include/media/omap3isp.h b/include/media/omap3isp.h
index e917b1d..042849a 100644
--- a/include/media/omap3isp.h
+++ b/include/media/omap3isp.h
@@ -58,7 +58,7 @@
  *		ISP_LANE_SHIFT_4 - CAMEXT[13:4] -> CAM[9:0]
  *		ISP_LANE_SHIFT_6 - CAMEXT[13:6] -> CAM[7:0]
  * @clk_pol: Pixel clock polarity
- *		0 - Non Inverted, 1 - Inverted
+ *		0 - Sample on rising edge, 1 - Sample on falling edge
  * @hs_pol: Horizontal synchronization polarity
  *		0 - Active high, 1 - Active low
  * @vs_pol: Vertical synchronization polarity
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index 26a3bd0..183d701 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -18,13 +18,15 @@
 #define RC_TYPE_JVC	(1  << 3)	/* JVC protocol */
 #define RC_TYPE_SONY	(1  << 4)	/* Sony12/15/20 protocol */
 #define RC_TYPE_RC5_SZ	(1  << 5)	/* RC5 variant used by Streamzap */
+#define RC_TYPE_SANYO   (1  << 6)	/* Sanyo protocol */
 #define RC_TYPE_MCE_KBD	(1  << 29)	/* RC6-ish MCE keyboard/mouse */
 #define RC_TYPE_LIRC	(1  << 30)	/* Pass raw IR to lirc userspace */
 #define RC_TYPE_OTHER	(1u << 31)
 
-#define RC_TYPE_ALL (RC_TYPE_RC5 | RC_TYPE_NEC  | RC_TYPE_RC6  | \
-		     RC_TYPE_JVC | RC_TYPE_SONY | RC_TYPE_LIRC | \
-		     RC_TYPE_RC5_SZ | RC_TYPE_MCE_KBD | RC_TYPE_OTHER)
+#define RC_TYPE_ALL (RC_TYPE_RC5    | RC_TYPE_NEC   | RC_TYPE_RC6     | \
+		     RC_TYPE_JVC    | RC_TYPE_SONY  | RC_TYPE_LIRC    | \
+		     RC_TYPE_RC5_SZ | RC_TYPE_SANYO | RC_TYPE_MCE_KBD | \
+		     RC_TYPE_OTHER)
 
 struct rc_map_table {
 	u32	scancode;