瀏覽代碼

Merge git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb

* git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (70 commits)
  V4L/DVB (7900): pvrusb: Fix Kconfig if DVB=m V4L_core=y
  V4L/DVB (7899): Fixes a few remaining Kbuild issues at common/tuners
  V4L/DVB (7898): Fix VIDEO_MEDIA Kconfig logic
  V4L/DVB (7895): tveeprom: update Hauppauge analog audio and video decoders
  V4L/DVB (7893): xc5000: bug-fix: allow multiple devices in a single system
  V4L/DVB (7891): cx18/ivtv: fix open() kernel oops
  V4L/DVB (7890): cx18: removed bogus and confusing conditional
  V4L/DVB (7889): cx18: improve HVR-1600 detection.
  V4L/DVB (7888): cx18: minor card definition updates.
  V4L/DVB (7887): cx18: fix Compro H900 analog support.
  V4L/DVB (7881): saa7134: fixed a compile warning in saa7134-core.c
  V4L/DVB (7880): saa7134: remove explicit GPIO initialization
  V4L/DVB(7879): Adding cx18 Support for mxl5005s
  V4L/DVB(7878): mxl55005s: Makefile and Kconfig additions
  V4L/DVB(7877): mxl5005s: Ensure debug is off
  V4L/DVB(7876): mxl5005s: Remove incorrect copyright holders
  V4L/DVB(7875): mxl5005s: Remove redundant functions
  V4L/DVB(7874): mxl5005s: Fix function statics
  V4L/DVB(7873): mxl5005s: Fix header includes.
  V4L/DVB(7872): mxl5005s: checkpatch.pl compliance
  ...
Linus Torvalds 17 年之前
父節點
當前提交
4717df5830
共有 76 個文件被更改,包括 4976 次插入498 次删除
  1. 1 1
      Documentation/video4linux/CARDLIST.cx23885
  2. 1 1
      Documentation/video4linux/CARDLIST.em28xx
  3. 9 0
      MAINTAINERS
  4. 1 2
      drivers/media/Kconfig
  5. 31 19
      drivers/media/common/tuners/Kconfig
  6. 1 0
      drivers/media/common/tuners/Makefile
  7. 4110 0
      drivers/media/common/tuners/mxl5005s.c
  8. 131 0
      drivers/media/common/tuners/mxl5005s.h
  9. 11 13
      drivers/media/common/tuners/tda18271-common.c
  10. 113 55
      drivers/media/common/tuners/tda18271-fe.c
  11. 9 0
      drivers/media/common/tuners/tda18271-priv.h
  12. 3 3
      drivers/media/common/tuners/tea5767.c
  13. 5 4
      drivers/media/common/tuners/xc5000.c
  14. 12 10
      drivers/media/common/tuners/xc5000.h
  15. 2 0
      drivers/media/common/tuners/xc5000_priv.h
  16. 1 1
      drivers/media/dvb/b2c2/flexcop-fe-tuner.c
  17. 1 0
      drivers/media/dvb/bt8xx/Kconfig
  18. 1 1
      drivers/media/dvb/cinergyT2/Kconfig
  19. 16 12
      drivers/media/dvb/dvb-core/dvb_ca_en50221.c
  20. 1 0
      drivers/media/dvb/dvb-usb/Kconfig
  21. 9 9
      drivers/media/dvb/frontends/Kconfig
  22. 1 1
      drivers/media/dvb/frontends/itd1000.c
  23. 5 4
      drivers/media/dvb/frontends/mt312.c
  24. 2 2
      drivers/media/dvb/frontends/mt312.h
  25. 2 0
      drivers/media/dvb/ttpci/Kconfig
  26. 1 0
      drivers/media/dvb/ttusb-dec/Kconfig
  27. 7 3
      drivers/media/video/Kconfig
  28. 1 1
      drivers/media/video/Makefile
  29. 2 1
      drivers/media/video/au0828/Kconfig
  30. 2 4
      drivers/media/video/au0828/au0828-dvb.c
  31. 2 1
      drivers/media/video/bt8xx/Kconfig
  32. 4 1
      drivers/media/video/cx18/Kconfig
  33. 14 11
      drivers/media/video/cx18/cx18-cards.c
  34. 3 2
      drivers/media/video/cx18/cx18-cards.h
  35. 11 18
      drivers/media/video/cx18/cx18-driver.c
  36. 0 3
      drivers/media/video/cx18/cx18-driver.h
  37. 19 21
      drivers/media/video/cx18/cx18-dvb.c
  38. 4 2
      drivers/media/video/cx18/cx18-fileops.c
  39. 0 9
      drivers/media/video/cx18/cx18-fileops.h
  40. 36 11
      drivers/media/video/cx18/cx18-gpio.c
  41. 1 0
      drivers/media/video/cx18/cx18-i2c.c
  42. 6 16
      drivers/media/video/cx18/cx18-queue.c
  43. 0 4
      drivers/media/video/cx18/cx18-queue.h
  44. 8 5
      drivers/media/video/cx18/cx18-streams.c
  45. 1 1
      drivers/media/video/cx18/cx18-streams.h
  46. 4 2
      drivers/media/video/cx23885/Kconfig
  47. 35 1
      drivers/media/video/cx23885/cx23885-cards.c
  48. 2 5
      drivers/media/video/cx23885/cx23885-dvb.c
  49. 1 0
      drivers/media/video/cx25840/Kconfig
  50. 3 3
      drivers/media/video/cx88/Kconfig
  51. 134 119
      drivers/media/video/cx88/cx88-dvb.c
  52. 1 2
      drivers/media/video/em28xx/Kconfig
  53. 7 1
      drivers/media/video/em28xx/em28xx-cards.c
  54. 0 1
      drivers/media/video/em28xx/em28xx-dvb.c
  55. 3 1
      drivers/media/video/ivtv/Kconfig
  56. 2 2
      drivers/media/video/ivtv/ivtv-controls.c
  57. 6 2
      drivers/media/video/ivtv/ivtv-driver.c
  58. 2 0
      drivers/media/video/ivtv/ivtv-fileops.c
  59. 8 8
      drivers/media/video/ivtv/ivtv-ioctl.c
  60. 3 3
      drivers/media/video/ivtv/ivtv-ioctl.h
  61. 7 5
      drivers/media/video/ivtv/ivtv-queue.c
  62. 8 5
      drivers/media/video/ivtv/ivtv-streams.c
  63. 1 1
      drivers/media/video/ivtv/ivtv-streams.h
  64. 2 1
      drivers/media/video/ivtv/ivtv-vbi.c
  65. 1 1
      drivers/media/video/ivtv/ivtv-yuv.c
  66. 4 2
      drivers/media/video/ivtv/ivtvfb.c
  67. 1 4
      drivers/media/video/mt9m001.c
  68. 2 5
      drivers/media/video/mt9v022.c
  69. 3 1
      drivers/media/video/pvrusb2/Kconfig
  70. 2 1
      drivers/media/video/saa7134/Kconfig
  71. 0 6
      drivers/media/video/saa7134/saa7134-core.c
  72. 100 40
      drivers/media/video/saa7134/saa7134-dvb.c
  73. 7 0
      drivers/media/video/stk-webcam.c
  74. 18 20
      drivers/media/video/tuner-core.c
  75. 7 3
      drivers/media/video/tveeprom.c
  76. 1 1
      drivers/media/video/usbvision/Kconfig

+ 1 - 1
Documentation/video4linux/CARDLIST.cx23885

@@ -5,6 +5,6 @@
   4 -> DViCO FusionHDTV5 Express                           [18ac:d500]
   4 -> DViCO FusionHDTV5 Express                           [18ac:d500]
   5 -> Hauppauge WinTV-HVR1500Q                            [0070:7790,0070:7797]
   5 -> Hauppauge WinTV-HVR1500Q                            [0070:7790,0070:7797]
   6 -> Hauppauge WinTV-HVR1500                             [0070:7710,0070:7717]
   6 -> Hauppauge WinTV-HVR1500                             [0070:7710,0070:7717]
-  7 -> Hauppauge WinTV-HVR1200                             [0070:71d1]
+  7 -> Hauppauge WinTV-HVR1200                             [0070:71d1,0070:71d3]
   8 -> Hauppauge WinTV-HVR1700                             [0070:8101]
   8 -> Hauppauge WinTV-HVR1700                             [0070:8101]
   9 -> Hauppauge WinTV-HVR1400                             [0070:8010]
   9 -> Hauppauge WinTV-HVR1400                             [0070:8010]

+ 1 - 1
Documentation/video4linux/CARDLIST.em28xx

@@ -14,4 +14,4 @@
  13 -> Terratec Prodigy XS                      (em2880)        [0ccd:0047]
  13 -> Terratec Prodigy XS                      (em2880)        [0ccd:0047]
  14 -> Pixelview Prolink PlayTV USB 2.0         (em2820/em2840)
  14 -> Pixelview Prolink PlayTV USB 2.0         (em2820/em2840)
  15 -> V-Gear PocketTV                          (em2800)
  15 -> V-Gear PocketTV                          (em2800)
- 16 -> Hauppauge WinTV HVR 950                  (em2880)        [2040:6513]
+ 16 -> Hauppauge WinTV HVR 950                  (em2880)        [2040:6513,2040:6517,2040:651b,2040:651f]

+ 9 - 0
MAINTAINERS

@@ -1230,6 +1230,15 @@ P:	Jaya Kumar
 M:	jayakumar.alsa@gmail.com
 M:	jayakumar.alsa@gmail.com
 S:	Maintained
 S:	Maintained
 
 
+CX18 VIDEO4LINUX DRIVER
+P:	Hans Verkuil, Andy Walls
+M:	hverkuil@xs4all.nl, awalls@radix.net
+L:	ivtv-devel@ivtvdriver.org
+L:	ivtv-users@ivtvdriver.org
+L:	video4linux-list@redhat.com
+W:	http://linuxtv.org
+S:	Maintained
+
 CYBERPRO FB DRIVER
 CYBERPRO FB DRIVER
 P:	Russell King
 P:	Russell King
 M:	rmk@arm.linux.org.uk
 M:	rmk@arm.linux.org.uk

+ 1 - 2
drivers/media/Kconfig

@@ -89,8 +89,7 @@ config DVB_CORE
 
 
 config VIDEO_MEDIA
 config VIDEO_MEDIA
 	tristate
 	tristate
-	default DVB_CORE || VIDEO_DEV
-	depends on DVB_CORE || VIDEO_DEV
+	default (DVB_CORE && (VIDEO_DEV = n)) || (VIDEO_DEV && (DVB_CORE = n)) || (DVB_CORE && VIDEO_DEV)
 
 
 comment "Multimedia drivers"
 comment "Multimedia drivers"
 
 

+ 31 - 19
drivers/media/common/tuners/Kconfig

@@ -1,6 +1,6 @@
 config MEDIA_ATTACH
 config MEDIA_ATTACH
 	bool "Load and attach frontend and tuner driver modules as needed"
 	bool "Load and attach frontend and tuner driver modules as needed"
-	depends on DVB_CORE
+	depends on VIDEO_MEDIA
 	depends on MODULES
 	depends on MODULES
 	help
 	help
 	  Remove the static dependency of DVB card drivers on all
 	  Remove the static dependency of DVB card drivers on all
@@ -19,10 +19,10 @@ config MEDIA_ATTACH
 
 
 config MEDIA_TUNER
 config MEDIA_TUNER
 	tristate
 	tristate
-	default DVB_CORE || VIDEO_DEV
-	depends on DVB_CORE || VIDEO_DEV
-	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE
-	select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE
+	default VIDEO_MEDIA && I2C
+	depends on VIDEO_MEDIA && I2C
+	select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG
+	select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG
 	select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE
 	select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE
 	select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE
 	select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE
 	select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE
 	select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE
@@ -46,7 +46,7 @@ if MEDIA_TUNER_CUSTOMIZE
 
 
 config MEDIA_TUNER_SIMPLE
 config MEDIA_TUNER_SIMPLE
 	tristate "Simple tuner support"
 	tristate "Simple tuner support"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
 	select MEDIA_TUNER_TDA9887
 	select MEDIA_TUNER_TDA9887
 	default m if MEDIA_TUNER_CUSTOMIZE
 	default m if MEDIA_TUNER_CUSTOMIZE
 	help
 	help
@@ -54,7 +54,7 @@ config MEDIA_TUNER_SIMPLE
 
 
 config MEDIA_TUNER_TDA8290
 config MEDIA_TUNER_TDA8290
 	tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo"
 	tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
 	select MEDIA_TUNER_TDA827X
 	select MEDIA_TUNER_TDA827X
 	select MEDIA_TUNER_TDA18271
 	select MEDIA_TUNER_TDA18271
 	default m if MEDIA_TUNER_CUSTOMIZE
 	default m if MEDIA_TUNER_CUSTOMIZE
@@ -63,21 +63,21 @@ config MEDIA_TUNER_TDA8290
 
 
 config MEDIA_TUNER_TDA827X
 config MEDIA_TUNER_TDA827X
 	tristate "Philips TDA827X silicon tuner"
 	tristate "Philips TDA827X silicon tuner"
-	depends on DVB_CORE && I2C
+	depends on VIDEO_MEDIA && I2C
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
 	help
 	help
 	  A DVB-T silicon tuner module. Say Y when you want to support this tuner.
 	  A DVB-T silicon tuner module. Say Y when you want to support this tuner.
 
 
 config MEDIA_TUNER_TDA18271
 config MEDIA_TUNER_TDA18271
 	tristate "NXP TDA18271 silicon tuner"
 	tristate "NXP TDA18271 silicon tuner"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
 	help
 	help
 	  A silicon tuner module. Say Y when you want to support this tuner.
 	  A silicon tuner module. Say Y when you want to support this tuner.
 
 
 config MEDIA_TUNER_TDA9887
 config MEDIA_TUNER_TDA9887
 	tristate "TDA 9885/6/7 analog IF demodulator"
 	tristate "TDA 9885/6/7 analog IF demodulator"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
 	default m if MEDIA_TUNER_CUSTOMIZE
 	default m if MEDIA_TUNER_CUSTOMIZE
 	help
 	help
 	  Say Y here to include support for Philips TDA9885/6/7
 	  Say Y here to include support for Philips TDA9885/6/7
@@ -85,67 +85,79 @@ config MEDIA_TUNER_TDA9887
 
 
 config MEDIA_TUNER_TEA5761
 config MEDIA_TUNER_TEA5761
 	tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
 	tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
-	depends on I2C && EXPERIMENTAL
+	depends on VIDEO_MEDIA && I2C
+	depends on EXPERIMENTAL
 	default m if MEDIA_TUNER_CUSTOMIZE
 	default m if MEDIA_TUNER_CUSTOMIZE
 	help
 	help
 	  Say Y here to include support for the Philips TEA5761 radio tuner.
 	  Say Y here to include support for the Philips TEA5761 radio tuner.
 
 
 config MEDIA_TUNER_TEA5767
 config MEDIA_TUNER_TEA5767
 	tristate "TEA 5767 radio tuner"
 	tristate "TEA 5767 radio tuner"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
 	default m if MEDIA_TUNER_CUSTOMIZE
 	default m if MEDIA_TUNER_CUSTOMIZE
 	help
 	help
 	  Say Y here to include support for the Philips TEA5767 radio tuner.
 	  Say Y here to include support for the Philips TEA5767 radio tuner.
 
 
 config MEDIA_TUNER_MT20XX
 config MEDIA_TUNER_MT20XX
 	tristate "Microtune 2032 / 2050 tuners"
 	tristate "Microtune 2032 / 2050 tuners"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
 	default m if MEDIA_TUNER_CUSTOMIZE
 	default m if MEDIA_TUNER_CUSTOMIZE
 	help
 	help
 	  Say Y here to include support for the MT2032 / MT2050 tuner.
 	  Say Y here to include support for the MT2032 / MT2050 tuner.
 
 
 config MEDIA_TUNER_MT2060
 config MEDIA_TUNER_MT2060
 	tristate "Microtune MT2060 silicon IF tuner"
 	tristate "Microtune MT2060 silicon IF tuner"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
 	help
 	help
 	  A driver for the silicon IF tuner MT2060 from Microtune.
 	  A driver for the silicon IF tuner MT2060 from Microtune.
 
 
 config MEDIA_TUNER_MT2266
 config MEDIA_TUNER_MT2266
 	tristate "Microtune MT2266 silicon tuner"
 	tristate "Microtune MT2266 silicon tuner"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
 	help
 	help
 	  A driver for the silicon baseband tuner MT2266 from Microtune.
 	  A driver for the silicon baseband tuner MT2266 from Microtune.
 
 
 config MEDIA_TUNER_MT2131
 config MEDIA_TUNER_MT2131
 	tristate "Microtune MT2131 silicon tuner"
 	tristate "Microtune MT2131 silicon tuner"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
 	help
 	help
 	  A driver for the silicon baseband tuner MT2131 from Microtune.
 	  A driver for the silicon baseband tuner MT2131 from Microtune.
 
 
 config MEDIA_TUNER_QT1010
 config MEDIA_TUNER_QT1010
 	tristate "Quantek QT1010 silicon tuner"
 	tristate "Quantek QT1010 silicon tuner"
-	depends on DVB_CORE && I2C
+	depends on VIDEO_MEDIA && I2C
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
 	help
 	help
 	  A driver for the silicon tuner QT1010 from Quantek.
 	  A driver for the silicon tuner QT1010 from Quantek.
 
 
 config MEDIA_TUNER_XC2028
 config MEDIA_TUNER_XC2028
 	tristate "XCeive xc2028/xc3028 tuners"
 	tristate "XCeive xc2028/xc3028 tuners"
-	depends on I2C && FW_LOADER
+	depends on VIDEO_MEDIA && I2C
+	depends on HOTPLUG
+	select FW_LOADER
 	default m if MEDIA_TUNER_CUSTOMIZE
 	default m if MEDIA_TUNER_CUSTOMIZE
 	help
 	help
 	  Say Y here to include support for the xc2028/xc3028 tuners.
 	  Say Y here to include support for the xc2028/xc3028 tuners.
 
 
 config MEDIA_TUNER_XC5000
 config MEDIA_TUNER_XC5000
 	tristate "Xceive XC5000 silicon tuner"
 	tristate "Xceive XC5000 silicon tuner"
-	depends on I2C
+	depends on VIDEO_MEDIA && I2C
+	depends on HOTPLUG
+	select FW_LOADER
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
 	help
 	help
 	  A driver for the silicon tuner XC5000 from Xceive.
 	  A driver for the silicon tuner XC5000 from Xceive.
 	  This device is only used inside a SiP called togther with a
 	  This device is only used inside a SiP called togther with a
 	  demodulator for now.
 	  demodulator for now.
 
 
+config MEDIA_TUNER_MXL5005S
+	tristate "MaxLinear MSL5005S silicon tuner"
+	depends on VIDEO_MEDIA && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  A driver for the silicon tuner MXL5005S from MaxLinear.
+
 endif # MEDIA_TUNER_CUSTOMIZE
 endif # MEDIA_TUNER_CUSTOMIZE

+ 1 - 0
drivers/media/common/tuners/Makefile

@@ -20,6 +20,7 @@ obj-$(CONFIG_MEDIA_TUNER_MT2060) += mt2060.o
 obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o
 obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o
 obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
 obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
 obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
 obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
+obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
 
 
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends

+ 4110 - 0
drivers/media/common/tuners/mxl5005s.c

@@ -0,0 +1,4110 @@
+/*
+    MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
+
+    Copyright (C) 2008 MaxLinear
+    Copyright (C) 2006 Steven Toth <stoth@hauppauge.com>
+      Functions:
+	mxl5005s_reset()
+	mxl5005s_writereg()
+	mxl5005s_writeregs()
+	mxl5005s_init()
+	mxl5005s_reconfigure()
+	mxl5005s_AssignTunerMode()
+	mxl5005s_set_params()
+	mxl5005s_get_frequency()
+	mxl5005s_get_bandwidth()
+	mxl5005s_release()
+	mxl5005s_attach()
+
+    Copyright (C) 2008 Realtek
+    Copyright (C) 2008 Jan Hoogenraad
+      Functions:
+	mxl5005s_SetRfFreqHz()
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+/*
+    History of this driver (Steven Toth):
+      I was given a public release of a linux driver that included
+      support for the MaxLinear MXL5005S silicon tuner. Analysis of
+      the tuner driver showed clearly three things.
+
+      1. The tuner driver didn't support the LinuxTV tuner API
+	 so the code Realtek added had to be removed.
+
+      2. A significant amount of the driver is reference driver code
+	 from MaxLinear, I felt it was important to identify and
+	 preserve this.
+
+      3. New code has to be added to interface correctly with the
+	 LinuxTV API, as a regular kernel module.
+
+      Other than the reference driver enum's, I've clearly marked
+      sections of the code and retained the copyright of the
+      respective owners.
+*/
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include "dvb_frontend.h"
+#include "mxl5005s.h"
+
+static int debug;
+
+#define dprintk(level, arg...) do {    \
+	if (level <= debug)            \
+		printk(arg);    \
+	} while (0)
+
+#define TUNER_REGS_NUM          104
+#define INITCTRL_NUM            40
+
+#ifdef _MXL_PRODUCTION
+#define CHCTRL_NUM              39
+#else
+#define CHCTRL_NUM              36
+#endif
+
+#define MXLCTRL_NUM             189
+#define MASTER_CONTROL_ADDR     9
+
+/* Enumeration of Master Control Register State */
+enum master_control_state {
+	MC_LOAD_START = 1,
+	MC_POWER_DOWN,
+	MC_SYNTH_RESET,
+	MC_SEQ_OFF
+};
+
+/* Enumeration of MXL5005 Tuner Modulation Type */
+enum {
+	MXL_DEFAULT_MODULATION = 0,
+	MXL_DVBT,
+	MXL_ATSC,
+	MXL_QAM,
+	MXL_ANALOG_CABLE,
+	MXL_ANALOG_OTA
+} tuner_modu_type;
+
+/* MXL5005 Tuner Register Struct */
+struct TunerReg {
+	u16 Reg_Num;	/* Tuner Register Address */
+	u16 Reg_Val;	/* Current sw programmed value waiting to be writen */
+};
+
+enum {
+	/* Initialization Control Names */
+	DN_IQTN_AMP_CUT = 1,       /* 1 */
+	BB_MODE,                   /* 2 */
+	BB_BUF,                    /* 3 */
+	BB_BUF_OA,                 /* 4 */
+	BB_ALPF_BANDSELECT,        /* 5 */
+	BB_IQSWAP,                 /* 6 */
+	BB_DLPF_BANDSEL,           /* 7 */
+	RFSYN_CHP_GAIN,            /* 8 */
+	RFSYN_EN_CHP_HIGAIN,       /* 9 */
+	AGC_IF,                    /* 10 */
+	AGC_RF,                    /* 11 */
+	IF_DIVVAL,                 /* 12 */
+	IF_VCO_BIAS,               /* 13 */
+	CHCAL_INT_MOD_IF,          /* 14 */
+	CHCAL_FRAC_MOD_IF,         /* 15 */
+	DRV_RES_SEL,               /* 16 */
+	I_DRIVER,                  /* 17 */
+	EN_AAF,                    /* 18 */
+	EN_3P,                     /* 19 */
+	EN_AUX_3P,                 /* 20 */
+	SEL_AAF_BAND,              /* 21 */
+	SEQ_ENCLK16_CLK_OUT,       /* 22 */
+	SEQ_SEL4_16B,              /* 23 */
+	XTAL_CAPSELECT,            /* 24 */
+	IF_SEL_DBL,                /* 25 */
+	RFSYN_R_DIV,               /* 26 */
+	SEQ_EXTSYNTHCALIF,         /* 27 */
+	SEQ_EXTDCCAL,              /* 28 */
+	AGC_EN_RSSI,               /* 29 */
+	RFA_ENCLKRFAGC,            /* 30 */
+	RFA_RSSI_REFH,             /* 31 */
+	RFA_RSSI_REF,              /* 32 */
+	RFA_RSSI_REFL,             /* 33 */
+	RFA_FLR,                   /* 34 */
+	RFA_CEIL,                  /* 35 */
+	SEQ_EXTIQFSMPULSE,         /* 36 */
+	OVERRIDE_1,                /* 37 */
+	BB_INITSTATE_DLPF_TUNE,    /* 38 */
+	TG_R_DIV,                  /* 39 */
+	EN_CHP_LIN_B,              /* 40 */
+
+	/* Channel Change Control Names */
+	DN_POLY = 51,              /* 51 */
+	DN_RFGAIN,                 /* 52 */
+	DN_CAP_RFLPF,              /* 53 */
+	DN_EN_VHFUHFBAR,           /* 54 */
+	DN_GAIN_ADJUST,            /* 55 */
+	DN_IQTNBUF_AMP,            /* 56 */
+	DN_IQTNGNBFBIAS_BST,       /* 57 */
+	RFSYN_EN_OUTMUX,           /* 58 */
+	RFSYN_SEL_VCO_OUT,         /* 59 */
+	RFSYN_SEL_VCO_HI,          /* 60 */
+	RFSYN_SEL_DIVM,            /* 61 */
+	RFSYN_RF_DIV_BIAS,         /* 62 */
+	DN_SEL_FREQ,               /* 63 */
+	RFSYN_VCO_BIAS,            /* 64 */
+	CHCAL_INT_MOD_RF,          /* 65 */
+	CHCAL_FRAC_MOD_RF,         /* 66 */
+	RFSYN_LPF_R,               /* 67 */
+	CHCAL_EN_INT_RF,           /* 68 */
+	TG_LO_DIVVAL,              /* 69 */
+	TG_LO_SELVAL,              /* 70 */
+	TG_DIV_VAL,                /* 71 */
+	TG_VCO_BIAS,               /* 72 */
+	SEQ_EXTPOWERUP,            /* 73 */
+	OVERRIDE_2,                /* 74 */
+	OVERRIDE_3,                /* 75 */
+	OVERRIDE_4,                /* 76 */
+	SEQ_FSM_PULSE,             /* 77 */
+	GPIO_4B,                   /* 78 */
+	GPIO_3B,                   /* 79 */
+	GPIO_4,                    /* 80 */
+	GPIO_3,                    /* 81 */
+	GPIO_1B,                   /* 82 */
+	DAC_A_ENABLE,              /* 83 */
+	DAC_B_ENABLE,              /* 84 */
+	DAC_DIN_A,                 /* 85 */
+	DAC_DIN_B,                 /* 86 */
+#ifdef _MXL_PRODUCTION
+	RFSYN_EN_DIV,              /* 87 */
+	RFSYN_DIVM,                /* 88 */
+	DN_BYPASS_AGC_I2C          /* 89 */
+#endif
+} MXL5005_ControlName;
+
+/*
+ * The following context is source code provided by MaxLinear.
+ * MaxLinear source code - Common_MXL.h (?)
+ */
+
+/* Constants */
+#define MXL5005S_REG_WRITING_TABLE_LEN_MAX	104
+#define MXL5005S_LATCH_BYTE			0xfe
+
+/* Register address, MSB, and LSB */
+#define MXL5005S_BB_IQSWAP_ADDR			59
+#define MXL5005S_BB_IQSWAP_MSB			0
+#define MXL5005S_BB_IQSWAP_LSB			0
+
+#define MXL5005S_BB_DLPF_BANDSEL_ADDR		53
+#define MXL5005S_BB_DLPF_BANDSEL_MSB		4
+#define MXL5005S_BB_DLPF_BANDSEL_LSB		3
+
+/* Standard modes */
+enum {
+	MXL5005S_STANDARD_DVBT,
+	MXL5005S_STANDARD_ATSC,
+};
+#define MXL5005S_STANDARD_MODE_NUM		2
+
+/* Bandwidth modes */
+enum {
+	MXL5005S_BANDWIDTH_6MHZ = 6000000,
+	MXL5005S_BANDWIDTH_7MHZ = 7000000,
+	MXL5005S_BANDWIDTH_8MHZ = 8000000,
+};
+#define MXL5005S_BANDWIDTH_MODE_NUM		3
+
+/* MXL5005 Tuner Control Struct */
+struct TunerControl {
+	u16 Ctrl_Num;	/* Control Number */
+	u16 size;	/* Number of bits to represent Value */
+	u16 addr[25];	/* Array of Tuner Register Address for each bit pos */
+	u16 bit[25];	/* Array of bit pos in Reg Addr for each bit pos */
+	u16 val[25];	/* Binary representation of Value */
+};
+
+/* MXL5005 Tuner Struct */
+struct mxl5005s_state {
+	u8	Mode;		/* 0: Analog Mode ; 1: Digital Mode */
+	u8	IF_Mode;	/* for Analog Mode, 0: zero IF; 1: low IF */
+	u32	Chan_Bandwidth;	/* filter  channel bandwidth (6, 7, 8) */
+	u32	IF_OUT;		/* Desired IF Out Frequency */
+	u16	IF_OUT_LOAD;	/* IF Out Load Resistor (200/300 Ohms) */
+	u32	RF_IN;		/* RF Input Frequency */
+	u32	Fxtal;		/* XTAL Frequency */
+	u8	AGC_Mode;	/* AGC Mode 0: Dual AGC; 1: Single AGC */
+	u16	TOP;		/* Value: take over point */
+	u8	CLOCK_OUT;	/* 0: turn off clk out; 1: turn on clock out */
+	u8	DIV_OUT;	/* 4MHz or 16MHz */
+	u8	CAPSELECT;	/* 0: disable On-Chip pulling cap; 1: enable */
+	u8	EN_RSSI;	/* 0: disable RSSI; 1: enable RSSI */
+
+	/* Modulation Type; */
+	/* 0 - Default;	1 - DVB-T; 2 - ATSC; 3 - QAM; 4 - Analog Cable */
+	u8	Mod_Type;
+
+	/* Tracking Filter Type */
+	/* 0 - Default; 1 - Off; 2 - Type C; 3 - Type C-H */
+	u8	TF_Type;
+
+	/* Calculated Settings */
+	u32	RF_LO;		/* Synth RF LO Frequency */
+	u32	IF_LO;		/* Synth IF LO Frequency */
+	u32	TG_LO;		/* Synth TG_LO Frequency */
+
+	/* Pointers to ControlName Arrays */
+	u16	Init_Ctrl_Num;		/* Number of INIT Control Names */
+	struct TunerControl
+		Init_Ctrl[INITCTRL_NUM]; /* INIT Control Names Array Pointer */
+
+	u16	CH_Ctrl_Num;		/* Number of CH Control Names */
+	struct TunerControl
+		CH_Ctrl[CHCTRL_NUM];	/* CH Control Name Array Pointer */
+
+	u16	MXL_Ctrl_Num;		/* Number of MXL Control Names */
+	struct TunerControl
+		MXL_Ctrl[MXLCTRL_NUM];	/* MXL Control Name Array Pointer */
+
+	/* Pointer to Tuner Register Array */
+	u16	TunerRegs_Num;		/* Number of Tuner Registers */
+	struct TunerReg
+		TunerRegs[TUNER_REGS_NUM]; /* Tuner Register Array Pointer */
+
+	/* Linux driver framework specific */
+	struct mxl5005s_config *config;
+	struct dvb_frontend *frontend;
+	struct i2c_adapter *i2c;
+
+	/* Cache values */
+	u32 current_mode;
+
+};
+
+static u16 MXL_GetMasterControl(u8 *MasterReg, int state);
+static u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value);
+static u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value);
+static void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit,
+	u8 bitVal);
+static u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 *RegNum,
+	u8 *RegVal, int *count);
+static u32 MXL_Ceiling(u32 value, u32 resolution);
+static u16 MXL_RegRead(struct dvb_frontend *fe, u8 RegNum, u8 *RegVal);
+static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum,
+	u32 value, u16 controlGroup);
+static u16 MXL_SetGPIO(struct dvb_frontend *fe, u8 GPIO_Num, u8 GPIO_Val);
+static u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 *RegNum,
+	u8 *RegVal, int *count);
+static u32 MXL_GetXtalInt(u32 Xtal_Freq);
+static u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq);
+static void MXL_SynthIFLO_Calc(struct dvb_frontend *fe);
+static void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe);
+static u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 *RegNum,
+	u8 *RegVal, int *count);
+static int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable,
+	u8 *datatable, u8 len);
+static u16 MXL_IFSynthInit(struct dvb_frontend *fe);
+static int mxl5005s_AssignTunerMode(struct dvb_frontend *fe, u32 mod_type,
+	u32 bandwidth);
+static int mxl5005s_reconfigure(struct dvb_frontend *fe, u32 mod_type,
+	u32 bandwidth);
+
+/* ----------------------------------------------------------------
+ * Begin: Custom code salvaged from the Realtek driver.
+ * Copyright (C) 2008 Realtek
+ * Copyright (C) 2008 Jan Hoogenraad
+ * This code is placed under the terms of the GNU General Public License
+ *
+ * Released by Realtek under GPLv2.
+ * Thanks to Realtek for a lot of support we received !
+ *
+ *  Revision: 080314 - original version
+ */
+
+static int mxl5005s_SetRfFreqHz(struct dvb_frontend *fe, unsigned long RfFreqHz)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	unsigned char AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
+	unsigned char ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
+	int TableLen;
+
+	u32 IfDivval = 0;
+	unsigned char MasterControlByte;
+
+	dprintk(1, "%s() freq=%ld\n", __func__, RfFreqHz);
+
+	/* Set MxL5005S tuner RF frequency according to example code. */
+
+	/* Tuner RF frequency setting stage 0 */
+	MXL_GetMasterControl(ByteTable, MC_SYNTH_RESET);
+	AddrTable[0] = MASTER_CONTROL_ADDR;
+	ByteTable[0] |= state->config->AgcMasterByte;
+
+	mxl5005s_writeregs(fe, AddrTable, ByteTable, 1);
+
+	/* Tuner RF frequency setting stage 1 */
+	MXL_TuneRF(fe, RfFreqHz);
+
+	MXL_ControlRead(fe, IF_DIVVAL, &IfDivval);
+
+	MXL_ControlWrite(fe, SEQ_FSM_PULSE, 0);
+	MXL_ControlWrite(fe, SEQ_EXTPOWERUP, 1);
+	MXL_ControlWrite(fe, IF_DIVVAL, 8);
+	MXL_GetCHRegister(fe, AddrTable, ByteTable, &TableLen);
+
+	MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START);
+	AddrTable[TableLen] = MASTER_CONTROL_ADDR ;
+	ByteTable[TableLen] = MasterControlByte |
+		state->config->AgcMasterByte;
+	TableLen += 1;
+
+	mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen);
+
+	/* Wait 30 ms. */
+	msleep(150);
+
+	/* Tuner RF frequency setting stage 2 */
+	MXL_ControlWrite(fe, SEQ_FSM_PULSE, 1);
+	MXL_ControlWrite(fe, IF_DIVVAL, IfDivval);
+	MXL_GetCHRegister_ZeroIF(fe, AddrTable, ByteTable, &TableLen);
+
+	MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START);
+	AddrTable[TableLen] = MASTER_CONTROL_ADDR ;
+	ByteTable[TableLen] = MasterControlByte |
+		state->config->AgcMasterByte ;
+	TableLen += 1;
+
+	mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen);
+
+	msleep(100);
+
+	return 0;
+}
+/* End: Custom code taken from the Realtek driver */
+
+/* ----------------------------------------------------------------
+ * Begin: Reference driver code found in the Realtek driver.
+ * Copyright (C) 2008 MaxLinear
+ */
+static u16 MXL5005_RegisterInit(struct dvb_frontend *fe)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	state->TunerRegs_Num = TUNER_REGS_NUM ;
+
+	state->TunerRegs[0].Reg_Num = 9 ;
+	state->TunerRegs[0].Reg_Val = 0x40 ;
+
+	state->TunerRegs[1].Reg_Num = 11 ;
+	state->TunerRegs[1].Reg_Val = 0x19 ;
+
+	state->TunerRegs[2].Reg_Num = 12 ;
+	state->TunerRegs[2].Reg_Val = 0x60 ;
+
+	state->TunerRegs[3].Reg_Num = 13 ;
+	state->TunerRegs[3].Reg_Val = 0x00 ;
+
+	state->TunerRegs[4].Reg_Num = 14 ;
+	state->TunerRegs[4].Reg_Val = 0x00 ;
+
+	state->TunerRegs[5].Reg_Num = 15 ;
+	state->TunerRegs[5].Reg_Val = 0xC0 ;
+
+	state->TunerRegs[6].Reg_Num = 16 ;
+	state->TunerRegs[6].Reg_Val = 0x00 ;
+
+	state->TunerRegs[7].Reg_Num = 17 ;
+	state->TunerRegs[7].Reg_Val = 0x00 ;
+
+	state->TunerRegs[8].Reg_Num = 18 ;
+	state->TunerRegs[8].Reg_Val = 0x00 ;
+
+	state->TunerRegs[9].Reg_Num = 19 ;
+	state->TunerRegs[9].Reg_Val = 0x34 ;
+
+	state->TunerRegs[10].Reg_Num = 21 ;
+	state->TunerRegs[10].Reg_Val = 0x00 ;
+
+	state->TunerRegs[11].Reg_Num = 22 ;
+	state->TunerRegs[11].Reg_Val = 0x6B ;
+
+	state->TunerRegs[12].Reg_Num = 23 ;
+	state->TunerRegs[12].Reg_Val = 0x35 ;
+
+	state->TunerRegs[13].Reg_Num = 24 ;
+	state->TunerRegs[13].Reg_Val = 0x70 ;
+
+	state->TunerRegs[14].Reg_Num = 25 ;
+	state->TunerRegs[14].Reg_Val = 0x3E ;
+
+	state->TunerRegs[15].Reg_Num = 26 ;
+	state->TunerRegs[15].Reg_Val = 0x82 ;
+
+	state->TunerRegs[16].Reg_Num = 31 ;
+	state->TunerRegs[16].Reg_Val = 0x00 ;
+
+	state->TunerRegs[17].Reg_Num = 32 ;
+	state->TunerRegs[17].Reg_Val = 0x40 ;
+
+	state->TunerRegs[18].Reg_Num = 33 ;
+	state->TunerRegs[18].Reg_Val = 0x53 ;
+
+	state->TunerRegs[19].Reg_Num = 34 ;
+	state->TunerRegs[19].Reg_Val = 0x81 ;
+
+	state->TunerRegs[20].Reg_Num = 35 ;
+	state->TunerRegs[20].Reg_Val = 0xC9 ;
+
+	state->TunerRegs[21].Reg_Num = 36 ;
+	state->TunerRegs[21].Reg_Val = 0x01 ;
+
+	state->TunerRegs[22].Reg_Num = 37 ;
+	state->TunerRegs[22].Reg_Val = 0x00 ;
+
+	state->TunerRegs[23].Reg_Num = 41 ;
+	state->TunerRegs[23].Reg_Val = 0x00 ;
+
+	state->TunerRegs[24].Reg_Num = 42 ;
+	state->TunerRegs[24].Reg_Val = 0xF8 ;
+
+	state->TunerRegs[25].Reg_Num = 43 ;
+	state->TunerRegs[25].Reg_Val = 0x43 ;
+
+	state->TunerRegs[26].Reg_Num = 44 ;
+	state->TunerRegs[26].Reg_Val = 0x20 ;
+
+	state->TunerRegs[27].Reg_Num = 45 ;
+	state->TunerRegs[27].Reg_Val = 0x80 ;
+
+	state->TunerRegs[28].Reg_Num = 46 ;
+	state->TunerRegs[28].Reg_Val = 0x88 ;
+
+	state->TunerRegs[29].Reg_Num = 47 ;
+	state->TunerRegs[29].Reg_Val = 0x86 ;
+
+	state->TunerRegs[30].Reg_Num = 48 ;
+	state->TunerRegs[30].Reg_Val = 0x00 ;
+
+	state->TunerRegs[31].Reg_Num = 49 ;
+	state->TunerRegs[31].Reg_Val = 0x00 ;
+
+	state->TunerRegs[32].Reg_Num = 53 ;
+	state->TunerRegs[32].Reg_Val = 0x94 ;
+
+	state->TunerRegs[33].Reg_Num = 54 ;
+	state->TunerRegs[33].Reg_Val = 0xFA ;
+
+	state->TunerRegs[34].Reg_Num = 55 ;
+	state->TunerRegs[34].Reg_Val = 0x92 ;
+
+	state->TunerRegs[35].Reg_Num = 56 ;
+	state->TunerRegs[35].Reg_Val = 0x80 ;
+
+	state->TunerRegs[36].Reg_Num = 57 ;
+	state->TunerRegs[36].Reg_Val = 0x41 ;
+
+	state->TunerRegs[37].Reg_Num = 58 ;
+	state->TunerRegs[37].Reg_Val = 0xDB ;
+
+	state->TunerRegs[38].Reg_Num = 59 ;
+	state->TunerRegs[38].Reg_Val = 0x00 ;
+
+	state->TunerRegs[39].Reg_Num = 60 ;
+	state->TunerRegs[39].Reg_Val = 0x00 ;
+
+	state->TunerRegs[40].Reg_Num = 61 ;
+	state->TunerRegs[40].Reg_Val = 0x00 ;
+
+	state->TunerRegs[41].Reg_Num = 62 ;
+	state->TunerRegs[41].Reg_Val = 0x00 ;
+
+	state->TunerRegs[42].Reg_Num = 65 ;
+	state->TunerRegs[42].Reg_Val = 0xF8 ;
+
+	state->TunerRegs[43].Reg_Num = 66 ;
+	state->TunerRegs[43].Reg_Val = 0xE4 ;
+
+	state->TunerRegs[44].Reg_Num = 67 ;
+	state->TunerRegs[44].Reg_Val = 0x90 ;
+
+	state->TunerRegs[45].Reg_Num = 68 ;
+	state->TunerRegs[45].Reg_Val = 0xC0 ;
+
+	state->TunerRegs[46].Reg_Num = 69 ;
+	state->TunerRegs[46].Reg_Val = 0x01 ;
+
+	state->TunerRegs[47].Reg_Num = 70 ;
+	state->TunerRegs[47].Reg_Val = 0x50 ;
+
+	state->TunerRegs[48].Reg_Num = 71 ;
+	state->TunerRegs[48].Reg_Val = 0x06 ;
+
+	state->TunerRegs[49].Reg_Num = 72 ;
+	state->TunerRegs[49].Reg_Val = 0x00 ;
+
+	state->TunerRegs[50].Reg_Num = 73 ;
+	state->TunerRegs[50].Reg_Val = 0x20 ;
+
+	state->TunerRegs[51].Reg_Num = 76 ;
+	state->TunerRegs[51].Reg_Val = 0xBB ;
+
+	state->TunerRegs[52].Reg_Num = 77 ;
+	state->TunerRegs[52].Reg_Val = 0x13 ;
+
+	state->TunerRegs[53].Reg_Num = 81 ;
+	state->TunerRegs[53].Reg_Val = 0x04 ;
+
+	state->TunerRegs[54].Reg_Num = 82 ;
+	state->TunerRegs[54].Reg_Val = 0x75 ;
+
+	state->TunerRegs[55].Reg_Num = 83 ;
+	state->TunerRegs[55].Reg_Val = 0x00 ;
+
+	state->TunerRegs[56].Reg_Num = 84 ;
+	state->TunerRegs[56].Reg_Val = 0x00 ;
+
+	state->TunerRegs[57].Reg_Num = 85 ;
+	state->TunerRegs[57].Reg_Val = 0x00 ;
+
+	state->TunerRegs[58].Reg_Num = 91 ;
+	state->TunerRegs[58].Reg_Val = 0x70 ;
+
+	state->TunerRegs[59].Reg_Num = 92 ;
+	state->TunerRegs[59].Reg_Val = 0x00 ;
+
+	state->TunerRegs[60].Reg_Num = 93 ;
+	state->TunerRegs[60].Reg_Val = 0x00 ;
+
+	state->TunerRegs[61].Reg_Num = 94 ;
+	state->TunerRegs[61].Reg_Val = 0x00 ;
+
+	state->TunerRegs[62].Reg_Num = 95 ;
+	state->TunerRegs[62].Reg_Val = 0x0C ;
+
+	state->TunerRegs[63].Reg_Num = 96 ;
+	state->TunerRegs[63].Reg_Val = 0x00 ;
+
+	state->TunerRegs[64].Reg_Num = 97 ;
+	state->TunerRegs[64].Reg_Val = 0x00 ;
+
+	state->TunerRegs[65].Reg_Num = 98 ;
+	state->TunerRegs[65].Reg_Val = 0xE2 ;
+
+	state->TunerRegs[66].Reg_Num = 99 ;
+	state->TunerRegs[66].Reg_Val = 0x00 ;
+
+	state->TunerRegs[67].Reg_Num = 100 ;
+	state->TunerRegs[67].Reg_Val = 0x00 ;
+
+	state->TunerRegs[68].Reg_Num = 101 ;
+	state->TunerRegs[68].Reg_Val = 0x12 ;
+
+	state->TunerRegs[69].Reg_Num = 102 ;
+	state->TunerRegs[69].Reg_Val = 0x80 ;
+
+	state->TunerRegs[70].Reg_Num = 103 ;
+	state->TunerRegs[70].Reg_Val = 0x32 ;
+
+	state->TunerRegs[71].Reg_Num = 104 ;
+	state->TunerRegs[71].Reg_Val = 0xB4 ;
+
+	state->TunerRegs[72].Reg_Num = 105 ;
+	state->TunerRegs[72].Reg_Val = 0x60 ;
+
+	state->TunerRegs[73].Reg_Num = 106 ;
+	state->TunerRegs[73].Reg_Val = 0x83 ;
+
+	state->TunerRegs[74].Reg_Num = 107 ;
+	state->TunerRegs[74].Reg_Val = 0x84 ;
+
+	state->TunerRegs[75].Reg_Num = 108 ;
+	state->TunerRegs[75].Reg_Val = 0x9C ;
+
+	state->TunerRegs[76].Reg_Num = 109 ;
+	state->TunerRegs[76].Reg_Val = 0x02 ;
+
+	state->TunerRegs[77].Reg_Num = 110 ;
+	state->TunerRegs[77].Reg_Val = 0x81 ;
+
+	state->TunerRegs[78].Reg_Num = 111 ;
+	state->TunerRegs[78].Reg_Val = 0xC0 ;
+
+	state->TunerRegs[79].Reg_Num = 112 ;
+	state->TunerRegs[79].Reg_Val = 0x10 ;
+
+	state->TunerRegs[80].Reg_Num = 131 ;
+	state->TunerRegs[80].Reg_Val = 0x8A ;
+
+	state->TunerRegs[81].Reg_Num = 132 ;
+	state->TunerRegs[81].Reg_Val = 0x10 ;
+
+	state->TunerRegs[82].Reg_Num = 133 ;
+	state->TunerRegs[82].Reg_Val = 0x24 ;
+
+	state->TunerRegs[83].Reg_Num = 134 ;
+	state->TunerRegs[83].Reg_Val = 0x00 ;
+
+	state->TunerRegs[84].Reg_Num = 135 ;
+	state->TunerRegs[84].Reg_Val = 0x00 ;
+
+	state->TunerRegs[85].Reg_Num = 136 ;
+	state->TunerRegs[85].Reg_Val = 0x7E ;
+
+	state->TunerRegs[86].Reg_Num = 137 ;
+	state->TunerRegs[86].Reg_Val = 0x40 ;
+
+	state->TunerRegs[87].Reg_Num = 138 ;
+	state->TunerRegs[87].Reg_Val = 0x38 ;
+
+	state->TunerRegs[88].Reg_Num = 146 ;
+	state->TunerRegs[88].Reg_Val = 0xF6 ;
+
+	state->TunerRegs[89].Reg_Num = 147 ;
+	state->TunerRegs[89].Reg_Val = 0x1A ;
+
+	state->TunerRegs[90].Reg_Num = 148 ;
+	state->TunerRegs[90].Reg_Val = 0x62 ;
+
+	state->TunerRegs[91].Reg_Num = 149 ;
+	state->TunerRegs[91].Reg_Val = 0x33 ;
+
+	state->TunerRegs[92].Reg_Num = 150 ;
+	state->TunerRegs[92].Reg_Val = 0x80 ;
+
+	state->TunerRegs[93].Reg_Num = 156 ;
+	state->TunerRegs[93].Reg_Val = 0x56 ;
+
+	state->TunerRegs[94].Reg_Num = 157 ;
+	state->TunerRegs[94].Reg_Val = 0x17 ;
+
+	state->TunerRegs[95].Reg_Num = 158 ;
+	state->TunerRegs[95].Reg_Val = 0xA9 ;
+
+	state->TunerRegs[96].Reg_Num = 159 ;
+	state->TunerRegs[96].Reg_Val = 0x00 ;
+
+	state->TunerRegs[97].Reg_Num = 160 ;
+	state->TunerRegs[97].Reg_Val = 0x00 ;
+
+	state->TunerRegs[98].Reg_Num = 161 ;
+	state->TunerRegs[98].Reg_Val = 0x00 ;
+
+	state->TunerRegs[99].Reg_Num = 162 ;
+	state->TunerRegs[99].Reg_Val = 0x40 ;
+
+	state->TunerRegs[100].Reg_Num = 166 ;
+	state->TunerRegs[100].Reg_Val = 0xAE ;
+
+	state->TunerRegs[101].Reg_Num = 167 ;
+	state->TunerRegs[101].Reg_Val = 0x1B ;
+
+	state->TunerRegs[102].Reg_Num = 168 ;
+	state->TunerRegs[102].Reg_Val = 0xF2 ;
+
+	state->TunerRegs[103].Reg_Num = 195 ;
+	state->TunerRegs[103].Reg_Val = 0x00 ;
+
+	return 0 ;
+}
+
+static u16 MXL5005_ControlInit(struct dvb_frontend *fe)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	state->Init_Ctrl_Num = INITCTRL_NUM;
+
+	state->Init_Ctrl[0].Ctrl_Num = DN_IQTN_AMP_CUT ;
+	state->Init_Ctrl[0].size = 1 ;
+	state->Init_Ctrl[0].addr[0] = 73;
+	state->Init_Ctrl[0].bit[0] = 7;
+	state->Init_Ctrl[0].val[0] = 0;
+
+	state->Init_Ctrl[1].Ctrl_Num = BB_MODE ;
+	state->Init_Ctrl[1].size = 1 ;
+	state->Init_Ctrl[1].addr[0] = 53;
+	state->Init_Ctrl[1].bit[0] = 2;
+	state->Init_Ctrl[1].val[0] = 1;
+
+	state->Init_Ctrl[2].Ctrl_Num = BB_BUF ;
+	state->Init_Ctrl[2].size = 2 ;
+	state->Init_Ctrl[2].addr[0] = 53;
+	state->Init_Ctrl[2].bit[0] = 1;
+	state->Init_Ctrl[2].val[0] = 0;
+	state->Init_Ctrl[2].addr[1] = 57;
+	state->Init_Ctrl[2].bit[1] = 0;
+	state->Init_Ctrl[2].val[1] = 1;
+
+	state->Init_Ctrl[3].Ctrl_Num = BB_BUF_OA ;
+	state->Init_Ctrl[3].size = 1 ;
+	state->Init_Ctrl[3].addr[0] = 53;
+	state->Init_Ctrl[3].bit[0] = 0;
+	state->Init_Ctrl[3].val[0] = 0;
+
+	state->Init_Ctrl[4].Ctrl_Num = BB_ALPF_BANDSELECT ;
+	state->Init_Ctrl[4].size = 3 ;
+	state->Init_Ctrl[4].addr[0] = 53;
+	state->Init_Ctrl[4].bit[0] = 5;
+	state->Init_Ctrl[4].val[0] = 0;
+	state->Init_Ctrl[4].addr[1] = 53;
+	state->Init_Ctrl[4].bit[1] = 6;
+	state->Init_Ctrl[4].val[1] = 0;
+	state->Init_Ctrl[4].addr[2] = 53;
+	state->Init_Ctrl[4].bit[2] = 7;
+	state->Init_Ctrl[4].val[2] = 1;
+
+	state->Init_Ctrl[5].Ctrl_Num = BB_IQSWAP ;
+	state->Init_Ctrl[5].size = 1 ;
+	state->Init_Ctrl[5].addr[0] = 59;
+	state->Init_Ctrl[5].bit[0] = 0;
+	state->Init_Ctrl[5].val[0] = 0;
+
+	state->Init_Ctrl[6].Ctrl_Num = BB_DLPF_BANDSEL ;
+	state->Init_Ctrl[6].size = 2 ;
+	state->Init_Ctrl[6].addr[0] = 53;
+	state->Init_Ctrl[6].bit[0] = 3;
+	state->Init_Ctrl[6].val[0] = 0;
+	state->Init_Ctrl[6].addr[1] = 53;
+	state->Init_Ctrl[6].bit[1] = 4;
+	state->Init_Ctrl[6].val[1] = 1;
+
+	state->Init_Ctrl[7].Ctrl_Num = RFSYN_CHP_GAIN ;
+	state->Init_Ctrl[7].size = 4 ;
+	state->Init_Ctrl[7].addr[0] = 22;
+	state->Init_Ctrl[7].bit[0] = 4;
+	state->Init_Ctrl[7].val[0] = 0;
+	state->Init_Ctrl[7].addr[1] = 22;
+	state->Init_Ctrl[7].bit[1] = 5;
+	state->Init_Ctrl[7].val[1] = 1;
+	state->Init_Ctrl[7].addr[2] = 22;
+	state->Init_Ctrl[7].bit[2] = 6;
+	state->Init_Ctrl[7].val[2] = 1;
+	state->Init_Ctrl[7].addr[3] = 22;
+	state->Init_Ctrl[7].bit[3] = 7;
+	state->Init_Ctrl[7].val[3] = 0;
+
+	state->Init_Ctrl[8].Ctrl_Num = RFSYN_EN_CHP_HIGAIN ;
+	state->Init_Ctrl[8].size = 1 ;
+	state->Init_Ctrl[8].addr[0] = 22;
+	state->Init_Ctrl[8].bit[0] = 2;
+	state->Init_Ctrl[8].val[0] = 0;
+
+	state->Init_Ctrl[9].Ctrl_Num = AGC_IF ;
+	state->Init_Ctrl[9].size = 4 ;
+	state->Init_Ctrl[9].addr[0] = 76;
+	state->Init_Ctrl[9].bit[0] = 0;
+	state->Init_Ctrl[9].val[0] = 1;
+	state->Init_Ctrl[9].addr[1] = 76;
+	state->Init_Ctrl[9].bit[1] = 1;
+	state->Init_Ctrl[9].val[1] = 1;
+	state->Init_Ctrl[9].addr[2] = 76;
+	state->Init_Ctrl[9].bit[2] = 2;
+	state->Init_Ctrl[9].val[2] = 0;
+	state->Init_Ctrl[9].addr[3] = 76;
+	state->Init_Ctrl[9].bit[3] = 3;
+	state->Init_Ctrl[9].val[3] = 1;
+
+	state->Init_Ctrl[10].Ctrl_Num = AGC_RF ;
+	state->Init_Ctrl[10].size = 4 ;
+	state->Init_Ctrl[10].addr[0] = 76;
+	state->Init_Ctrl[10].bit[0] = 4;
+	state->Init_Ctrl[10].val[0] = 1;
+	state->Init_Ctrl[10].addr[1] = 76;
+	state->Init_Ctrl[10].bit[1] = 5;
+	state->Init_Ctrl[10].val[1] = 1;
+	state->Init_Ctrl[10].addr[2] = 76;
+	state->Init_Ctrl[10].bit[2] = 6;
+	state->Init_Ctrl[10].val[2] = 0;
+	state->Init_Ctrl[10].addr[3] = 76;
+	state->Init_Ctrl[10].bit[3] = 7;
+	state->Init_Ctrl[10].val[3] = 1;
+
+	state->Init_Ctrl[11].Ctrl_Num = IF_DIVVAL ;
+	state->Init_Ctrl[11].size = 5 ;
+	state->Init_Ctrl[11].addr[0] = 43;
+	state->Init_Ctrl[11].bit[0] = 3;
+	state->Init_Ctrl[11].val[0] = 0;
+	state->Init_Ctrl[11].addr[1] = 43;
+	state->Init_Ctrl[11].bit[1] = 4;
+	state->Init_Ctrl[11].val[1] = 0;
+	state->Init_Ctrl[11].addr[2] = 43;
+	state->Init_Ctrl[11].bit[2] = 5;
+	state->Init_Ctrl[11].val[2] = 0;
+	state->Init_Ctrl[11].addr[3] = 43;
+	state->Init_Ctrl[11].bit[3] = 6;
+	state->Init_Ctrl[11].val[3] = 1;
+	state->Init_Ctrl[11].addr[4] = 43;
+	state->Init_Ctrl[11].bit[4] = 7;
+	state->Init_Ctrl[11].val[4] = 0;
+
+	state->Init_Ctrl[12].Ctrl_Num = IF_VCO_BIAS ;
+	state->Init_Ctrl[12].size = 6 ;
+	state->Init_Ctrl[12].addr[0] = 44;
+	state->Init_Ctrl[12].bit[0] = 2;
+	state->Init_Ctrl[12].val[0] = 0;
+	state->Init_Ctrl[12].addr[1] = 44;
+	state->Init_Ctrl[12].bit[1] = 3;
+	state->Init_Ctrl[12].val[1] = 0;
+	state->Init_Ctrl[12].addr[2] = 44;
+	state->Init_Ctrl[12].bit[2] = 4;
+	state->Init_Ctrl[12].val[2] = 0;
+	state->Init_Ctrl[12].addr[3] = 44;
+	state->Init_Ctrl[12].bit[3] = 5;
+	state->Init_Ctrl[12].val[3] = 1;
+	state->Init_Ctrl[12].addr[4] = 44;
+	state->Init_Ctrl[12].bit[4] = 6;
+	state->Init_Ctrl[12].val[4] = 0;
+	state->Init_Ctrl[12].addr[5] = 44;
+	state->Init_Ctrl[12].bit[5] = 7;
+	state->Init_Ctrl[12].val[5] = 0;
+
+	state->Init_Ctrl[13].Ctrl_Num = CHCAL_INT_MOD_IF ;
+	state->Init_Ctrl[13].size = 7 ;
+	state->Init_Ctrl[13].addr[0] = 11;
+	state->Init_Ctrl[13].bit[0] = 0;
+	state->Init_Ctrl[13].val[0] = 1;
+	state->Init_Ctrl[13].addr[1] = 11;
+	state->Init_Ctrl[13].bit[1] = 1;
+	state->Init_Ctrl[13].val[1] = 0;
+	state->Init_Ctrl[13].addr[2] = 11;
+	state->Init_Ctrl[13].bit[2] = 2;
+	state->Init_Ctrl[13].val[2] = 0;
+	state->Init_Ctrl[13].addr[3] = 11;
+	state->Init_Ctrl[13].bit[3] = 3;
+	state->Init_Ctrl[13].val[3] = 1;
+	state->Init_Ctrl[13].addr[4] = 11;
+	state->Init_Ctrl[13].bit[4] = 4;
+	state->Init_Ctrl[13].val[4] = 1;
+	state->Init_Ctrl[13].addr[5] = 11;
+	state->Init_Ctrl[13].bit[5] = 5;
+	state->Init_Ctrl[13].val[5] = 0;
+	state->Init_Ctrl[13].addr[6] = 11;
+	state->Init_Ctrl[13].bit[6] = 6;
+	state->Init_Ctrl[13].val[6] = 0;
+
+	state->Init_Ctrl[14].Ctrl_Num = CHCAL_FRAC_MOD_IF ;
+	state->Init_Ctrl[14].size = 16 ;
+	state->Init_Ctrl[14].addr[0] = 13;
+	state->Init_Ctrl[14].bit[0] = 0;
+	state->Init_Ctrl[14].val[0] = 0;
+	state->Init_Ctrl[14].addr[1] = 13;
+	state->Init_Ctrl[14].bit[1] = 1;
+	state->Init_Ctrl[14].val[1] = 0;
+	state->Init_Ctrl[14].addr[2] = 13;
+	state->Init_Ctrl[14].bit[2] = 2;
+	state->Init_Ctrl[14].val[2] = 0;
+	state->Init_Ctrl[14].addr[3] = 13;
+	state->Init_Ctrl[14].bit[3] = 3;
+	state->Init_Ctrl[14].val[3] = 0;
+	state->Init_Ctrl[14].addr[4] = 13;
+	state->Init_Ctrl[14].bit[4] = 4;
+	state->Init_Ctrl[14].val[4] = 0;
+	state->Init_Ctrl[14].addr[5] = 13;
+	state->Init_Ctrl[14].bit[5] = 5;
+	state->Init_Ctrl[14].val[5] = 0;
+	state->Init_Ctrl[14].addr[6] = 13;
+	state->Init_Ctrl[14].bit[6] = 6;
+	state->Init_Ctrl[14].val[6] = 0;
+	state->Init_Ctrl[14].addr[7] = 13;
+	state->Init_Ctrl[14].bit[7] = 7;
+	state->Init_Ctrl[14].val[7] = 0;
+	state->Init_Ctrl[14].addr[8] = 12;
+	state->Init_Ctrl[14].bit[8] = 0;
+	state->Init_Ctrl[14].val[8] = 0;
+	state->Init_Ctrl[14].addr[9] = 12;
+	state->Init_Ctrl[14].bit[9] = 1;
+	state->Init_Ctrl[14].val[9] = 0;
+	state->Init_Ctrl[14].addr[10] = 12;
+	state->Init_Ctrl[14].bit[10] = 2;
+	state->Init_Ctrl[14].val[10] = 0;
+	state->Init_Ctrl[14].addr[11] = 12;
+	state->Init_Ctrl[14].bit[11] = 3;
+	state->Init_Ctrl[14].val[11] = 0;
+	state->Init_Ctrl[14].addr[12] = 12;
+	state->Init_Ctrl[14].bit[12] = 4;
+	state->Init_Ctrl[14].val[12] = 0;
+	state->Init_Ctrl[14].addr[13] = 12;
+	state->Init_Ctrl[14].bit[13] = 5;
+	state->Init_Ctrl[14].val[13] = 1;
+	state->Init_Ctrl[14].addr[14] = 12;
+	state->Init_Ctrl[14].bit[14] = 6;
+	state->Init_Ctrl[14].val[14] = 1;
+	state->Init_Ctrl[14].addr[15] = 12;
+	state->Init_Ctrl[14].bit[15] = 7;
+	state->Init_Ctrl[14].val[15] = 0;
+
+	state->Init_Ctrl[15].Ctrl_Num = DRV_RES_SEL ;
+	state->Init_Ctrl[15].size = 3 ;
+	state->Init_Ctrl[15].addr[0] = 147;
+	state->Init_Ctrl[15].bit[0] = 2;
+	state->Init_Ctrl[15].val[0] = 0;
+	state->Init_Ctrl[15].addr[1] = 147;
+	state->Init_Ctrl[15].bit[1] = 3;
+	state->Init_Ctrl[15].val[1] = 1;
+	state->Init_Ctrl[15].addr[2] = 147;
+	state->Init_Ctrl[15].bit[2] = 4;
+	state->Init_Ctrl[15].val[2] = 1;
+
+	state->Init_Ctrl[16].Ctrl_Num = I_DRIVER ;
+	state->Init_Ctrl[16].size = 2 ;
+	state->Init_Ctrl[16].addr[0] = 147;
+	state->Init_Ctrl[16].bit[0] = 0;
+	state->Init_Ctrl[16].val[0] = 0;
+	state->Init_Ctrl[16].addr[1] = 147;
+	state->Init_Ctrl[16].bit[1] = 1;
+	state->Init_Ctrl[16].val[1] = 1;
+
+	state->Init_Ctrl[17].Ctrl_Num = EN_AAF ;
+	state->Init_Ctrl[17].size = 1 ;
+	state->Init_Ctrl[17].addr[0] = 147;
+	state->Init_Ctrl[17].bit[0] = 7;
+	state->Init_Ctrl[17].val[0] = 0;
+
+	state->Init_Ctrl[18].Ctrl_Num = EN_3P ;
+	state->Init_Ctrl[18].size = 1 ;
+	state->Init_Ctrl[18].addr[0] = 147;
+	state->Init_Ctrl[18].bit[0] = 6;
+	state->Init_Ctrl[18].val[0] = 0;
+
+	state->Init_Ctrl[19].Ctrl_Num = EN_AUX_3P ;
+	state->Init_Ctrl[19].size = 1 ;
+	state->Init_Ctrl[19].addr[0] = 156;
+	state->Init_Ctrl[19].bit[0] = 0;
+	state->Init_Ctrl[19].val[0] = 0;
+
+	state->Init_Ctrl[20].Ctrl_Num = SEL_AAF_BAND ;
+	state->Init_Ctrl[20].size = 1 ;
+	state->Init_Ctrl[20].addr[0] = 147;
+	state->Init_Ctrl[20].bit[0] = 5;
+	state->Init_Ctrl[20].val[0] = 0;
+
+	state->Init_Ctrl[21].Ctrl_Num = SEQ_ENCLK16_CLK_OUT ;
+	state->Init_Ctrl[21].size = 1 ;
+	state->Init_Ctrl[21].addr[0] = 137;
+	state->Init_Ctrl[21].bit[0] = 4;
+	state->Init_Ctrl[21].val[0] = 0;
+
+	state->Init_Ctrl[22].Ctrl_Num = SEQ_SEL4_16B ;
+	state->Init_Ctrl[22].size = 1 ;
+	state->Init_Ctrl[22].addr[0] = 137;
+	state->Init_Ctrl[22].bit[0] = 7;
+	state->Init_Ctrl[22].val[0] = 0;
+
+	state->Init_Ctrl[23].Ctrl_Num = XTAL_CAPSELECT ;
+	state->Init_Ctrl[23].size = 1 ;
+	state->Init_Ctrl[23].addr[0] = 91;
+	state->Init_Ctrl[23].bit[0] = 5;
+	state->Init_Ctrl[23].val[0] = 1;
+
+	state->Init_Ctrl[24].Ctrl_Num = IF_SEL_DBL ;
+	state->Init_Ctrl[24].size = 1 ;
+	state->Init_Ctrl[24].addr[0] = 43;
+	state->Init_Ctrl[24].bit[0] = 0;
+	state->Init_Ctrl[24].val[0] = 1;
+
+	state->Init_Ctrl[25].Ctrl_Num = RFSYN_R_DIV ;
+	state->Init_Ctrl[25].size = 2 ;
+	state->Init_Ctrl[25].addr[0] = 22;
+	state->Init_Ctrl[25].bit[0] = 0;
+	state->Init_Ctrl[25].val[0] = 1;
+	state->Init_Ctrl[25].addr[1] = 22;
+	state->Init_Ctrl[25].bit[1] = 1;
+	state->Init_Ctrl[25].val[1] = 1;
+
+	state->Init_Ctrl[26].Ctrl_Num = SEQ_EXTSYNTHCALIF ;
+	state->Init_Ctrl[26].size = 1 ;
+	state->Init_Ctrl[26].addr[0] = 134;
+	state->Init_Ctrl[26].bit[0] = 2;
+	state->Init_Ctrl[26].val[0] = 0;
+
+	state->Init_Ctrl[27].Ctrl_Num = SEQ_EXTDCCAL ;
+	state->Init_Ctrl[27].size = 1 ;
+	state->Init_Ctrl[27].addr[0] = 137;
+	state->Init_Ctrl[27].bit[0] = 3;
+	state->Init_Ctrl[27].val[0] = 0;
+
+	state->Init_Ctrl[28].Ctrl_Num = AGC_EN_RSSI ;
+	state->Init_Ctrl[28].size = 1 ;
+	state->Init_Ctrl[28].addr[0] = 77;
+	state->Init_Ctrl[28].bit[0] = 7;
+	state->Init_Ctrl[28].val[0] = 0;
+
+	state->Init_Ctrl[29].Ctrl_Num = RFA_ENCLKRFAGC ;
+	state->Init_Ctrl[29].size = 1 ;
+	state->Init_Ctrl[29].addr[0] = 166;
+	state->Init_Ctrl[29].bit[0] = 7;
+	state->Init_Ctrl[29].val[0] = 1;
+
+	state->Init_Ctrl[30].Ctrl_Num = RFA_RSSI_REFH ;
+	state->Init_Ctrl[30].size = 3 ;
+	state->Init_Ctrl[30].addr[0] = 166;
+	state->Init_Ctrl[30].bit[0] = 0;
+	state->Init_Ctrl[30].val[0] = 0;
+	state->Init_Ctrl[30].addr[1] = 166;
+	state->Init_Ctrl[30].bit[1] = 1;
+	state->Init_Ctrl[30].val[1] = 1;
+	state->Init_Ctrl[30].addr[2] = 166;
+	state->Init_Ctrl[30].bit[2] = 2;
+	state->Init_Ctrl[30].val[2] = 1;
+
+	state->Init_Ctrl[31].Ctrl_Num = RFA_RSSI_REF ;
+	state->Init_Ctrl[31].size = 3 ;
+	state->Init_Ctrl[31].addr[0] = 166;
+	state->Init_Ctrl[31].bit[0] = 3;
+	state->Init_Ctrl[31].val[0] = 1;
+	state->Init_Ctrl[31].addr[1] = 166;
+	state->Init_Ctrl[31].bit[1] = 4;
+	state->Init_Ctrl[31].val[1] = 0;
+	state->Init_Ctrl[31].addr[2] = 166;
+	state->Init_Ctrl[31].bit[2] = 5;
+	state->Init_Ctrl[31].val[2] = 1;
+
+	state->Init_Ctrl[32].Ctrl_Num = RFA_RSSI_REFL ;
+	state->Init_Ctrl[32].size = 3 ;
+	state->Init_Ctrl[32].addr[0] = 167;
+	state->Init_Ctrl[32].bit[0] = 0;
+	state->Init_Ctrl[32].val[0] = 1;
+	state->Init_Ctrl[32].addr[1] = 167;
+	state->Init_Ctrl[32].bit[1] = 1;
+	state->Init_Ctrl[32].val[1] = 1;
+	state->Init_Ctrl[32].addr[2] = 167;
+	state->Init_Ctrl[32].bit[2] = 2;
+	state->Init_Ctrl[32].val[2] = 0;
+
+	state->Init_Ctrl[33].Ctrl_Num = RFA_FLR ;
+	state->Init_Ctrl[33].size = 4 ;
+	state->Init_Ctrl[33].addr[0] = 168;
+	state->Init_Ctrl[33].bit[0] = 0;
+	state->Init_Ctrl[33].val[0] = 0;
+	state->Init_Ctrl[33].addr[1] = 168;
+	state->Init_Ctrl[33].bit[1] = 1;
+	state->Init_Ctrl[33].val[1] = 1;
+	state->Init_Ctrl[33].addr[2] = 168;
+	state->Init_Ctrl[33].bit[2] = 2;
+	state->Init_Ctrl[33].val[2] = 0;
+	state->Init_Ctrl[33].addr[3] = 168;
+	state->Init_Ctrl[33].bit[3] = 3;
+	state->Init_Ctrl[33].val[3] = 0;
+
+	state->Init_Ctrl[34].Ctrl_Num = RFA_CEIL ;
+	state->Init_Ctrl[34].size = 4 ;
+	state->Init_Ctrl[34].addr[0] = 168;
+	state->Init_Ctrl[34].bit[0] = 4;
+	state->Init_Ctrl[34].val[0] = 1;
+	state->Init_Ctrl[34].addr[1] = 168;
+	state->Init_Ctrl[34].bit[1] = 5;
+	state->Init_Ctrl[34].val[1] = 1;
+	state->Init_Ctrl[34].addr[2] = 168;
+	state->Init_Ctrl[34].bit[2] = 6;
+	state->Init_Ctrl[34].val[2] = 1;
+	state->Init_Ctrl[34].addr[3] = 168;
+	state->Init_Ctrl[34].bit[3] = 7;
+	state->Init_Ctrl[34].val[3] = 1;
+
+	state->Init_Ctrl[35].Ctrl_Num = SEQ_EXTIQFSMPULSE ;
+	state->Init_Ctrl[35].size = 1 ;
+	state->Init_Ctrl[35].addr[0] = 135;
+	state->Init_Ctrl[35].bit[0] = 0;
+	state->Init_Ctrl[35].val[0] = 0;
+
+	state->Init_Ctrl[36].Ctrl_Num = OVERRIDE_1 ;
+	state->Init_Ctrl[36].size = 1 ;
+	state->Init_Ctrl[36].addr[0] = 56;
+	state->Init_Ctrl[36].bit[0] = 3;
+	state->Init_Ctrl[36].val[0] = 0;
+
+	state->Init_Ctrl[37].Ctrl_Num = BB_INITSTATE_DLPF_TUNE ;
+	state->Init_Ctrl[37].size = 7 ;
+	state->Init_Ctrl[37].addr[0] = 59;
+	state->Init_Ctrl[37].bit[0] = 1;
+	state->Init_Ctrl[37].val[0] = 0;
+	state->Init_Ctrl[37].addr[1] = 59;
+	state->Init_Ctrl[37].bit[1] = 2;
+	state->Init_Ctrl[37].val[1] = 0;
+	state->Init_Ctrl[37].addr[2] = 59;
+	state->Init_Ctrl[37].bit[2] = 3;
+	state->Init_Ctrl[37].val[2] = 0;
+	state->Init_Ctrl[37].addr[3] = 59;
+	state->Init_Ctrl[37].bit[3] = 4;
+	state->Init_Ctrl[37].val[3] = 0;
+	state->Init_Ctrl[37].addr[4] = 59;
+	state->Init_Ctrl[37].bit[4] = 5;
+	state->Init_Ctrl[37].val[4] = 0;
+	state->Init_Ctrl[37].addr[5] = 59;
+	state->Init_Ctrl[37].bit[5] = 6;
+	state->Init_Ctrl[37].val[5] = 0;
+	state->Init_Ctrl[37].addr[6] = 59;
+	state->Init_Ctrl[37].bit[6] = 7;
+	state->Init_Ctrl[37].val[6] = 0;
+
+	state->Init_Ctrl[38].Ctrl_Num = TG_R_DIV ;
+	state->Init_Ctrl[38].size = 6 ;
+	state->Init_Ctrl[38].addr[0] = 32;
+	state->Init_Ctrl[38].bit[0] = 2;
+	state->Init_Ctrl[38].val[0] = 0;
+	state->Init_Ctrl[38].addr[1] = 32;
+	state->Init_Ctrl[38].bit[1] = 3;
+	state->Init_Ctrl[38].val[1] = 0;
+	state->Init_Ctrl[38].addr[2] = 32;
+	state->Init_Ctrl[38].bit[2] = 4;
+	state->Init_Ctrl[38].val[2] = 0;
+	state->Init_Ctrl[38].addr[3] = 32;
+	state->Init_Ctrl[38].bit[3] = 5;
+	state->Init_Ctrl[38].val[3] = 0;
+	state->Init_Ctrl[38].addr[4] = 32;
+	state->Init_Ctrl[38].bit[4] = 6;
+	state->Init_Ctrl[38].val[4] = 1;
+	state->Init_Ctrl[38].addr[5] = 32;
+	state->Init_Ctrl[38].bit[5] = 7;
+	state->Init_Ctrl[38].val[5] = 0;
+
+	state->Init_Ctrl[39].Ctrl_Num = EN_CHP_LIN_B ;
+	state->Init_Ctrl[39].size = 1 ;
+	state->Init_Ctrl[39].addr[0] = 25;
+	state->Init_Ctrl[39].bit[0] = 3;
+	state->Init_Ctrl[39].val[0] = 1;
+
+
+	state->CH_Ctrl_Num = CHCTRL_NUM ;
+
+	state->CH_Ctrl[0].Ctrl_Num = DN_POLY ;
+	state->CH_Ctrl[0].size = 2 ;
+	state->CH_Ctrl[0].addr[0] = 68;
+	state->CH_Ctrl[0].bit[0] = 6;
+	state->CH_Ctrl[0].val[0] = 1;
+	state->CH_Ctrl[0].addr[1] = 68;
+	state->CH_Ctrl[0].bit[1] = 7;
+	state->CH_Ctrl[0].val[1] = 1;
+
+	state->CH_Ctrl[1].Ctrl_Num = DN_RFGAIN ;
+	state->CH_Ctrl[1].size = 2 ;
+	state->CH_Ctrl[1].addr[0] = 70;
+	state->CH_Ctrl[1].bit[0] = 6;
+	state->CH_Ctrl[1].val[0] = 1;
+	state->CH_Ctrl[1].addr[1] = 70;
+	state->CH_Ctrl[1].bit[1] = 7;
+	state->CH_Ctrl[1].val[1] = 0;
+
+	state->CH_Ctrl[2].Ctrl_Num = DN_CAP_RFLPF ;
+	state->CH_Ctrl[2].size = 9 ;
+	state->CH_Ctrl[2].addr[0] = 69;
+	state->CH_Ctrl[2].bit[0] = 5;
+	state->CH_Ctrl[2].val[0] = 0;
+	state->CH_Ctrl[2].addr[1] = 69;
+	state->CH_Ctrl[2].bit[1] = 6;
+	state->CH_Ctrl[2].val[1] = 0;
+	state->CH_Ctrl[2].addr[2] = 69;
+	state->CH_Ctrl[2].bit[2] = 7;
+	state->CH_Ctrl[2].val[2] = 0;
+	state->CH_Ctrl[2].addr[3] = 68;
+	state->CH_Ctrl[2].bit[3] = 0;
+	state->CH_Ctrl[2].val[3] = 0;
+	state->CH_Ctrl[2].addr[4] = 68;
+	state->CH_Ctrl[2].bit[4] = 1;
+	state->CH_Ctrl[2].val[4] = 0;
+	state->CH_Ctrl[2].addr[5] = 68;
+	state->CH_Ctrl[2].bit[5] = 2;
+	state->CH_Ctrl[2].val[5] = 0;
+	state->CH_Ctrl[2].addr[6] = 68;
+	state->CH_Ctrl[2].bit[6] = 3;
+	state->CH_Ctrl[2].val[6] = 0;
+	state->CH_Ctrl[2].addr[7] = 68;
+	state->CH_Ctrl[2].bit[7] = 4;
+	state->CH_Ctrl[2].val[7] = 0;
+	state->CH_Ctrl[2].addr[8] = 68;
+	state->CH_Ctrl[2].bit[8] = 5;
+	state->CH_Ctrl[2].val[8] = 0;
+
+	state->CH_Ctrl[3].Ctrl_Num = DN_EN_VHFUHFBAR ;
+	state->CH_Ctrl[3].size = 1 ;
+	state->CH_Ctrl[3].addr[0] = 70;
+	state->CH_Ctrl[3].bit[0] = 5;
+	state->CH_Ctrl[3].val[0] = 0;
+
+	state->CH_Ctrl[4].Ctrl_Num = DN_GAIN_ADJUST ;
+	state->CH_Ctrl[4].size = 3 ;
+	state->CH_Ctrl[4].addr[0] = 73;
+	state->CH_Ctrl[4].bit[0] = 4;
+	state->CH_Ctrl[4].val[0] = 0;
+	state->CH_Ctrl[4].addr[1] = 73;
+	state->CH_Ctrl[4].bit[1] = 5;
+	state->CH_Ctrl[4].val[1] = 1;
+	state->CH_Ctrl[4].addr[2] = 73;
+	state->CH_Ctrl[4].bit[2] = 6;
+	state->CH_Ctrl[4].val[2] = 0;
+
+	state->CH_Ctrl[5].Ctrl_Num = DN_IQTNBUF_AMP ;
+	state->CH_Ctrl[5].size = 4 ;
+	state->CH_Ctrl[5].addr[0] = 70;
+	state->CH_Ctrl[5].bit[0] = 0;
+	state->CH_Ctrl[5].val[0] = 0;
+	state->CH_Ctrl[5].addr[1] = 70;
+	state->CH_Ctrl[5].bit[1] = 1;
+	state->CH_Ctrl[5].val[1] = 0;
+	state->CH_Ctrl[5].addr[2] = 70;
+	state->CH_Ctrl[5].bit[2] = 2;
+	state->CH_Ctrl[5].val[2] = 0;
+	state->CH_Ctrl[5].addr[3] = 70;
+	state->CH_Ctrl[5].bit[3] = 3;
+	state->CH_Ctrl[5].val[3] = 0;
+
+	state->CH_Ctrl[6].Ctrl_Num = DN_IQTNGNBFBIAS_BST ;
+	state->CH_Ctrl[6].size = 1 ;
+	state->CH_Ctrl[6].addr[0] = 70;
+	state->CH_Ctrl[6].bit[0] = 4;
+	state->CH_Ctrl[6].val[0] = 1;
+
+	state->CH_Ctrl[7].Ctrl_Num = RFSYN_EN_OUTMUX ;
+	state->CH_Ctrl[7].size = 1 ;
+	state->CH_Ctrl[7].addr[0] = 111;
+	state->CH_Ctrl[7].bit[0] = 4;
+	state->CH_Ctrl[7].val[0] = 0;
+
+	state->CH_Ctrl[8].Ctrl_Num = RFSYN_SEL_VCO_OUT ;
+	state->CH_Ctrl[8].size = 1 ;
+	state->CH_Ctrl[8].addr[0] = 111;
+	state->CH_Ctrl[8].bit[0] = 7;
+	state->CH_Ctrl[8].val[0] = 1;
+
+	state->CH_Ctrl[9].Ctrl_Num = RFSYN_SEL_VCO_HI ;
+	state->CH_Ctrl[9].size = 1 ;
+	state->CH_Ctrl[9].addr[0] = 111;
+	state->CH_Ctrl[9].bit[0] = 6;
+	state->CH_Ctrl[9].val[0] = 1;
+
+	state->CH_Ctrl[10].Ctrl_Num = RFSYN_SEL_DIVM ;
+	state->CH_Ctrl[10].size = 1 ;
+	state->CH_Ctrl[10].addr[0] = 111;
+	state->CH_Ctrl[10].bit[0] = 5;
+	state->CH_Ctrl[10].val[0] = 0;
+
+	state->CH_Ctrl[11].Ctrl_Num = RFSYN_RF_DIV_BIAS ;
+	state->CH_Ctrl[11].size = 2 ;
+	state->CH_Ctrl[11].addr[0] = 110;
+	state->CH_Ctrl[11].bit[0] = 0;
+	state->CH_Ctrl[11].val[0] = 1;
+	state->CH_Ctrl[11].addr[1] = 110;
+	state->CH_Ctrl[11].bit[1] = 1;
+	state->CH_Ctrl[11].val[1] = 0;
+
+	state->CH_Ctrl[12].Ctrl_Num = DN_SEL_FREQ ;
+	state->CH_Ctrl[12].size = 3 ;
+	state->CH_Ctrl[12].addr[0] = 69;
+	state->CH_Ctrl[12].bit[0] = 2;
+	state->CH_Ctrl[12].val[0] = 0;
+	state->CH_Ctrl[12].addr[1] = 69;
+	state->CH_Ctrl[12].bit[1] = 3;
+	state->CH_Ctrl[12].val[1] = 0;
+	state->CH_Ctrl[12].addr[2] = 69;
+	state->CH_Ctrl[12].bit[2] = 4;
+	state->CH_Ctrl[12].val[2] = 0;
+
+	state->CH_Ctrl[13].Ctrl_Num = RFSYN_VCO_BIAS ;
+	state->CH_Ctrl[13].size = 6 ;
+	state->CH_Ctrl[13].addr[0] = 110;
+	state->CH_Ctrl[13].bit[0] = 2;
+	state->CH_Ctrl[13].val[0] = 0;
+	state->CH_Ctrl[13].addr[1] = 110;
+	state->CH_Ctrl[13].bit[1] = 3;
+	state->CH_Ctrl[13].val[1] = 0;
+	state->CH_Ctrl[13].addr[2] = 110;
+	state->CH_Ctrl[13].bit[2] = 4;
+	state->CH_Ctrl[13].val[2] = 0;
+	state->CH_Ctrl[13].addr[3] = 110;
+	state->CH_Ctrl[13].bit[3] = 5;
+	state->CH_Ctrl[13].val[3] = 0;
+	state->CH_Ctrl[13].addr[4] = 110;
+	state->CH_Ctrl[13].bit[4] = 6;
+	state->CH_Ctrl[13].val[4] = 0;
+	state->CH_Ctrl[13].addr[5] = 110;
+	state->CH_Ctrl[13].bit[5] = 7;
+	state->CH_Ctrl[13].val[5] = 1;
+
+	state->CH_Ctrl[14].Ctrl_Num = CHCAL_INT_MOD_RF ;
+	state->CH_Ctrl[14].size = 7 ;
+	state->CH_Ctrl[14].addr[0] = 14;
+	state->CH_Ctrl[14].bit[0] = 0;
+	state->CH_Ctrl[14].val[0] = 0;
+	state->CH_Ctrl[14].addr[1] = 14;
+	state->CH_Ctrl[14].bit[1] = 1;
+	state->CH_Ctrl[14].val[1] = 0;
+	state->CH_Ctrl[14].addr[2] = 14;
+	state->CH_Ctrl[14].bit[2] = 2;
+	state->CH_Ctrl[14].val[2] = 0;
+	state->CH_Ctrl[14].addr[3] = 14;
+	state->CH_Ctrl[14].bit[3] = 3;
+	state->CH_Ctrl[14].val[3] = 0;
+	state->CH_Ctrl[14].addr[4] = 14;
+	state->CH_Ctrl[14].bit[4] = 4;
+	state->CH_Ctrl[14].val[4] = 0;
+	state->CH_Ctrl[14].addr[5] = 14;
+	state->CH_Ctrl[14].bit[5] = 5;
+	state->CH_Ctrl[14].val[5] = 0;
+	state->CH_Ctrl[14].addr[6] = 14;
+	state->CH_Ctrl[14].bit[6] = 6;
+	state->CH_Ctrl[14].val[6] = 0;
+
+	state->CH_Ctrl[15].Ctrl_Num = CHCAL_FRAC_MOD_RF ;
+	state->CH_Ctrl[15].size = 18 ;
+	state->CH_Ctrl[15].addr[0] = 17;
+	state->CH_Ctrl[15].bit[0] = 6;
+	state->CH_Ctrl[15].val[0] = 0;
+	state->CH_Ctrl[15].addr[1] = 17;
+	state->CH_Ctrl[15].bit[1] = 7;
+	state->CH_Ctrl[15].val[1] = 0;
+	state->CH_Ctrl[15].addr[2] = 16;
+	state->CH_Ctrl[15].bit[2] = 0;
+	state->CH_Ctrl[15].val[2] = 0;
+	state->CH_Ctrl[15].addr[3] = 16;
+	state->CH_Ctrl[15].bit[3] = 1;
+	state->CH_Ctrl[15].val[3] = 0;
+	state->CH_Ctrl[15].addr[4] = 16;
+	state->CH_Ctrl[15].bit[4] = 2;
+	state->CH_Ctrl[15].val[4] = 0;
+	state->CH_Ctrl[15].addr[5] = 16;
+	state->CH_Ctrl[15].bit[5] = 3;
+	state->CH_Ctrl[15].val[5] = 0;
+	state->CH_Ctrl[15].addr[6] = 16;
+	state->CH_Ctrl[15].bit[6] = 4;
+	state->CH_Ctrl[15].val[6] = 0;
+	state->CH_Ctrl[15].addr[7] = 16;
+	state->CH_Ctrl[15].bit[7] = 5;
+	state->CH_Ctrl[15].val[7] = 0;
+	state->CH_Ctrl[15].addr[8] = 16;
+	state->CH_Ctrl[15].bit[8] = 6;
+	state->CH_Ctrl[15].val[8] = 0;
+	state->CH_Ctrl[15].addr[9] = 16;
+	state->CH_Ctrl[15].bit[9] = 7;
+	state->CH_Ctrl[15].val[9] = 0;
+	state->CH_Ctrl[15].addr[10] = 15;
+	state->CH_Ctrl[15].bit[10] = 0;
+	state->CH_Ctrl[15].val[10] = 0;
+	state->CH_Ctrl[15].addr[11] = 15;
+	state->CH_Ctrl[15].bit[11] = 1;
+	state->CH_Ctrl[15].val[11] = 0;
+	state->CH_Ctrl[15].addr[12] = 15;
+	state->CH_Ctrl[15].bit[12] = 2;
+	state->CH_Ctrl[15].val[12] = 0;
+	state->CH_Ctrl[15].addr[13] = 15;
+	state->CH_Ctrl[15].bit[13] = 3;
+	state->CH_Ctrl[15].val[13] = 0;
+	state->CH_Ctrl[15].addr[14] = 15;
+	state->CH_Ctrl[15].bit[14] = 4;
+	state->CH_Ctrl[15].val[14] = 0;
+	state->CH_Ctrl[15].addr[15] = 15;
+	state->CH_Ctrl[15].bit[15] = 5;
+	state->CH_Ctrl[15].val[15] = 0;
+	state->CH_Ctrl[15].addr[16] = 15;
+	state->CH_Ctrl[15].bit[16] = 6;
+	state->CH_Ctrl[15].val[16] = 1;
+	state->CH_Ctrl[15].addr[17] = 15;
+	state->CH_Ctrl[15].bit[17] = 7;
+	state->CH_Ctrl[15].val[17] = 1;
+
+	state->CH_Ctrl[16].Ctrl_Num = RFSYN_LPF_R ;
+	state->CH_Ctrl[16].size = 5 ;
+	state->CH_Ctrl[16].addr[0] = 112;
+	state->CH_Ctrl[16].bit[0] = 0;
+	state->CH_Ctrl[16].val[0] = 0;
+	state->CH_Ctrl[16].addr[1] = 112;
+	state->CH_Ctrl[16].bit[1] = 1;
+	state->CH_Ctrl[16].val[1] = 0;
+	state->CH_Ctrl[16].addr[2] = 112;
+	state->CH_Ctrl[16].bit[2] = 2;
+	state->CH_Ctrl[16].val[2] = 0;
+	state->CH_Ctrl[16].addr[3] = 112;
+	state->CH_Ctrl[16].bit[3] = 3;
+	state->CH_Ctrl[16].val[3] = 0;
+	state->CH_Ctrl[16].addr[4] = 112;
+	state->CH_Ctrl[16].bit[4] = 4;
+	state->CH_Ctrl[16].val[4] = 1;
+
+	state->CH_Ctrl[17].Ctrl_Num = CHCAL_EN_INT_RF ;
+	state->CH_Ctrl[17].size = 1 ;
+	state->CH_Ctrl[17].addr[0] = 14;
+	state->CH_Ctrl[17].bit[0] = 7;
+	state->CH_Ctrl[17].val[0] = 0;
+
+	state->CH_Ctrl[18].Ctrl_Num = TG_LO_DIVVAL ;
+	state->CH_Ctrl[18].size = 4 ;
+	state->CH_Ctrl[18].addr[0] = 107;
+	state->CH_Ctrl[18].bit[0] = 3;
+	state->CH_Ctrl[18].val[0] = 0;
+	state->CH_Ctrl[18].addr[1] = 107;
+	state->CH_Ctrl[18].bit[1] = 4;
+	state->CH_Ctrl[18].val[1] = 0;
+	state->CH_Ctrl[18].addr[2] = 107;
+	state->CH_Ctrl[18].bit[2] = 5;
+	state->CH_Ctrl[18].val[2] = 0;
+	state->CH_Ctrl[18].addr[3] = 107;
+	state->CH_Ctrl[18].bit[3] = 6;
+	state->CH_Ctrl[18].val[3] = 0;
+
+	state->CH_Ctrl[19].Ctrl_Num = TG_LO_SELVAL ;
+	state->CH_Ctrl[19].size = 3 ;
+	state->CH_Ctrl[19].addr[0] = 107;
+	state->CH_Ctrl[19].bit[0] = 7;
+	state->CH_Ctrl[19].val[0] = 1;
+	state->CH_Ctrl[19].addr[1] = 106;
+	state->CH_Ctrl[19].bit[1] = 0;
+	state->CH_Ctrl[19].val[1] = 1;
+	state->CH_Ctrl[19].addr[2] = 106;
+	state->CH_Ctrl[19].bit[2] = 1;
+	state->CH_Ctrl[19].val[2] = 1;
+
+	state->CH_Ctrl[20].Ctrl_Num = TG_DIV_VAL ;
+	state->CH_Ctrl[20].size = 11 ;
+	state->CH_Ctrl[20].addr[0] = 109;
+	state->CH_Ctrl[20].bit[0] = 2;
+	state->CH_Ctrl[20].val[0] = 0;
+	state->CH_Ctrl[20].addr[1] = 109;
+	state->CH_Ctrl[20].bit[1] = 3;
+	state->CH_Ctrl[20].val[1] = 0;
+	state->CH_Ctrl[20].addr[2] = 109;
+	state->CH_Ctrl[20].bit[2] = 4;
+	state->CH_Ctrl[20].val[2] = 0;
+	state->CH_Ctrl[20].addr[3] = 109;
+	state->CH_Ctrl[20].bit[3] = 5;
+	state->CH_Ctrl[20].val[3] = 0;
+	state->CH_Ctrl[20].addr[4] = 109;
+	state->CH_Ctrl[20].bit[4] = 6;
+	state->CH_Ctrl[20].val[4] = 0;
+	state->CH_Ctrl[20].addr[5] = 109;
+	state->CH_Ctrl[20].bit[5] = 7;
+	state->CH_Ctrl[20].val[5] = 0;
+	state->CH_Ctrl[20].addr[6] = 108;
+	state->CH_Ctrl[20].bit[6] = 0;
+	state->CH_Ctrl[20].val[6] = 0;
+	state->CH_Ctrl[20].addr[7] = 108;
+	state->CH_Ctrl[20].bit[7] = 1;
+	state->CH_Ctrl[20].val[7] = 0;
+	state->CH_Ctrl[20].addr[8] = 108;
+	state->CH_Ctrl[20].bit[8] = 2;
+	state->CH_Ctrl[20].val[8] = 1;
+	state->CH_Ctrl[20].addr[9] = 108;
+	state->CH_Ctrl[20].bit[9] = 3;
+	state->CH_Ctrl[20].val[9] = 1;
+	state->CH_Ctrl[20].addr[10] = 108;
+	state->CH_Ctrl[20].bit[10] = 4;
+	state->CH_Ctrl[20].val[10] = 1;
+
+	state->CH_Ctrl[21].Ctrl_Num = TG_VCO_BIAS ;
+	state->CH_Ctrl[21].size = 6 ;
+	state->CH_Ctrl[21].addr[0] = 106;
+	state->CH_Ctrl[21].bit[0] = 2;
+	state->CH_Ctrl[21].val[0] = 0;
+	state->CH_Ctrl[21].addr[1] = 106;
+	state->CH_Ctrl[21].bit[1] = 3;
+	state->CH_Ctrl[21].val[1] = 0;
+	state->CH_Ctrl[21].addr[2] = 106;
+	state->CH_Ctrl[21].bit[2] = 4;
+	state->CH_Ctrl[21].val[2] = 0;
+	state->CH_Ctrl[21].addr[3] = 106;
+	state->CH_Ctrl[21].bit[3] = 5;
+	state->CH_Ctrl[21].val[3] = 0;
+	state->CH_Ctrl[21].addr[4] = 106;
+	state->CH_Ctrl[21].bit[4] = 6;
+	state->CH_Ctrl[21].val[4] = 0;
+	state->CH_Ctrl[21].addr[5] = 106;
+	state->CH_Ctrl[21].bit[5] = 7;
+	state->CH_Ctrl[21].val[5] = 1;
+
+	state->CH_Ctrl[22].Ctrl_Num = SEQ_EXTPOWERUP ;
+	state->CH_Ctrl[22].size = 1 ;
+	state->CH_Ctrl[22].addr[0] = 138;
+	state->CH_Ctrl[22].bit[0] = 4;
+	state->CH_Ctrl[22].val[0] = 1;
+
+	state->CH_Ctrl[23].Ctrl_Num = OVERRIDE_2 ;
+	state->CH_Ctrl[23].size = 1 ;
+	state->CH_Ctrl[23].addr[0] = 17;
+	state->CH_Ctrl[23].bit[0] = 5;
+	state->CH_Ctrl[23].val[0] = 0;
+
+	state->CH_Ctrl[24].Ctrl_Num = OVERRIDE_3 ;
+	state->CH_Ctrl[24].size = 1 ;
+	state->CH_Ctrl[24].addr[0] = 111;
+	state->CH_Ctrl[24].bit[0] = 3;
+	state->CH_Ctrl[24].val[0] = 0;
+
+	state->CH_Ctrl[25].Ctrl_Num = OVERRIDE_4 ;
+	state->CH_Ctrl[25].size = 1 ;
+	state->CH_Ctrl[25].addr[0] = 112;
+	state->CH_Ctrl[25].bit[0] = 7;
+	state->CH_Ctrl[25].val[0] = 0;
+
+	state->CH_Ctrl[26].Ctrl_Num = SEQ_FSM_PULSE ;
+	state->CH_Ctrl[26].size = 1 ;
+	state->CH_Ctrl[26].addr[0] = 136;
+	state->CH_Ctrl[26].bit[0] = 7;
+	state->CH_Ctrl[26].val[0] = 0;
+
+	state->CH_Ctrl[27].Ctrl_Num = GPIO_4B ;
+	state->CH_Ctrl[27].size = 1 ;
+	state->CH_Ctrl[27].addr[0] = 149;
+	state->CH_Ctrl[27].bit[0] = 7;
+	state->CH_Ctrl[27].val[0] = 0;
+
+	state->CH_Ctrl[28].Ctrl_Num = GPIO_3B ;
+	state->CH_Ctrl[28].size = 1 ;
+	state->CH_Ctrl[28].addr[0] = 149;
+	state->CH_Ctrl[28].bit[0] = 6;
+	state->CH_Ctrl[28].val[0] = 0;
+
+	state->CH_Ctrl[29].Ctrl_Num = GPIO_4 ;
+	state->CH_Ctrl[29].size = 1 ;
+	state->CH_Ctrl[29].addr[0] = 149;
+	state->CH_Ctrl[29].bit[0] = 5;
+	state->CH_Ctrl[29].val[0] = 1;
+
+	state->CH_Ctrl[30].Ctrl_Num = GPIO_3 ;
+	state->CH_Ctrl[30].size = 1 ;
+	state->CH_Ctrl[30].addr[0] = 149;
+	state->CH_Ctrl[30].bit[0] = 4;
+	state->CH_Ctrl[30].val[0] = 1;
+
+	state->CH_Ctrl[31].Ctrl_Num = GPIO_1B ;
+	state->CH_Ctrl[31].size = 1 ;
+	state->CH_Ctrl[31].addr[0] = 149;
+	state->CH_Ctrl[31].bit[0] = 3;
+	state->CH_Ctrl[31].val[0] = 0;
+
+	state->CH_Ctrl[32].Ctrl_Num = DAC_A_ENABLE ;
+	state->CH_Ctrl[32].size = 1 ;
+	state->CH_Ctrl[32].addr[0] = 93;
+	state->CH_Ctrl[32].bit[0] = 1;
+	state->CH_Ctrl[32].val[0] = 0;
+
+	state->CH_Ctrl[33].Ctrl_Num = DAC_B_ENABLE ;
+	state->CH_Ctrl[33].size = 1 ;
+	state->CH_Ctrl[33].addr[0] = 93;
+	state->CH_Ctrl[33].bit[0] = 0;
+	state->CH_Ctrl[33].val[0] = 0;
+
+	state->CH_Ctrl[34].Ctrl_Num = DAC_DIN_A ;
+	state->CH_Ctrl[34].size = 6 ;
+	state->CH_Ctrl[34].addr[0] = 92;
+	state->CH_Ctrl[34].bit[0] = 2;
+	state->CH_Ctrl[34].val[0] = 0;
+	state->CH_Ctrl[34].addr[1] = 92;
+	state->CH_Ctrl[34].bit[1] = 3;
+	state->CH_Ctrl[34].val[1] = 0;
+	state->CH_Ctrl[34].addr[2] = 92;
+	state->CH_Ctrl[34].bit[2] = 4;
+	state->CH_Ctrl[34].val[2] = 0;
+	state->CH_Ctrl[34].addr[3] = 92;
+	state->CH_Ctrl[34].bit[3] = 5;
+	state->CH_Ctrl[34].val[3] = 0;
+	state->CH_Ctrl[34].addr[4] = 92;
+	state->CH_Ctrl[34].bit[4] = 6;
+	state->CH_Ctrl[34].val[4] = 0;
+	state->CH_Ctrl[34].addr[5] = 92;
+	state->CH_Ctrl[34].bit[5] = 7;
+	state->CH_Ctrl[34].val[5] = 0;
+
+	state->CH_Ctrl[35].Ctrl_Num = DAC_DIN_B ;
+	state->CH_Ctrl[35].size = 6 ;
+	state->CH_Ctrl[35].addr[0] = 93;
+	state->CH_Ctrl[35].bit[0] = 2;
+	state->CH_Ctrl[35].val[0] = 0;
+	state->CH_Ctrl[35].addr[1] = 93;
+	state->CH_Ctrl[35].bit[1] = 3;
+	state->CH_Ctrl[35].val[1] = 0;
+	state->CH_Ctrl[35].addr[2] = 93;
+	state->CH_Ctrl[35].bit[2] = 4;
+	state->CH_Ctrl[35].val[2] = 0;
+	state->CH_Ctrl[35].addr[3] = 93;
+	state->CH_Ctrl[35].bit[3] = 5;
+	state->CH_Ctrl[35].val[3] = 0;
+	state->CH_Ctrl[35].addr[4] = 93;
+	state->CH_Ctrl[35].bit[4] = 6;
+	state->CH_Ctrl[35].val[4] = 0;
+	state->CH_Ctrl[35].addr[5] = 93;
+	state->CH_Ctrl[35].bit[5] = 7;
+	state->CH_Ctrl[35].val[5] = 0;
+
+#ifdef _MXL_PRODUCTION
+	state->CH_Ctrl[36].Ctrl_Num = RFSYN_EN_DIV ;
+	state->CH_Ctrl[36].size = 1 ;
+	state->CH_Ctrl[36].addr[0] = 109;
+	state->CH_Ctrl[36].bit[0] = 1;
+	state->CH_Ctrl[36].val[0] = 1;
+
+	state->CH_Ctrl[37].Ctrl_Num = RFSYN_DIVM ;
+	state->CH_Ctrl[37].size = 2 ;
+	state->CH_Ctrl[37].addr[0] = 112;
+	state->CH_Ctrl[37].bit[0] = 5;
+	state->CH_Ctrl[37].val[0] = 0;
+	state->CH_Ctrl[37].addr[1] = 112;
+	state->CH_Ctrl[37].bit[1] = 6;
+	state->CH_Ctrl[37].val[1] = 0;
+
+	state->CH_Ctrl[38].Ctrl_Num = DN_BYPASS_AGC_I2C ;
+	state->CH_Ctrl[38].size = 1 ;
+	state->CH_Ctrl[38].addr[0] = 65;
+	state->CH_Ctrl[38].bit[0] = 1;
+	state->CH_Ctrl[38].val[0] = 0;
+#endif
+
+	return 0 ;
+}
+
+static void InitTunerControls(struct dvb_frontend *fe)
+{
+	MXL5005_RegisterInit(fe);
+	MXL5005_ControlInit(fe);
+#ifdef _MXL_INTERNAL
+	MXL5005_MXLControlInit(fe);
+#endif
+}
+
+static u16 MXL5005_TunerConfig(struct dvb_frontend *fe,
+	u8	Mode,		/* 0: Analog Mode ; 1: Digital Mode */
+	u8	IF_mode,	/* for Analog Mode, 0: zero IF; 1: low IF */
+	u32	Bandwidth,	/* filter  channel bandwidth (6, 7, 8) */
+	u32	IF_out,		/* Desired IF Out Frequency */
+	u32	Fxtal,		/* XTAL Frequency */
+	u8	AGC_Mode,	/* AGC Mode - Dual AGC: 0, Single AGC: 1 */
+	u16	TOP,		/* 0: Dual AGC; Value: take over point */
+	u16	IF_OUT_LOAD,	/* IF Out Load Resistor (200 / 300 Ohms) */
+	u8	CLOCK_OUT, 	/* 0: turn off clk out; 1: turn on clock out */
+	u8	DIV_OUT,	/* 0: Div-1; 1: Div-4 */
+	u8	CAPSELECT, 	/* 0: disable On-Chip pulling cap; 1: enable */
+	u8	EN_RSSI, 	/* 0: disable RSSI; 1: enable RSSI */
+
+	/* Modulation Type; */
+	/* 0 - Default;	1 - DVB-T; 2 - ATSC; 3 - QAM; 4 - Analog Cable */
+	u8	Mod_Type,
+
+	/* Tracking Filter */
+	/* 0 - Default; 1 - Off; 2 - Type C; 3 - Type C-H */
+	u8	TF_Type
+	)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u16 status = 0;
+
+	state->Mode = Mode;
+	state->IF_Mode = IF_mode;
+	state->Chan_Bandwidth = Bandwidth;
+	state->IF_OUT = IF_out;
+	state->Fxtal = Fxtal;
+	state->AGC_Mode = AGC_Mode;
+	state->TOP = TOP;
+	state->IF_OUT_LOAD = IF_OUT_LOAD;
+	state->CLOCK_OUT = CLOCK_OUT;
+	state->DIV_OUT = DIV_OUT;
+	state->CAPSELECT = CAPSELECT;
+	state->EN_RSSI = EN_RSSI;
+	state->Mod_Type = Mod_Type;
+	state->TF_Type = TF_Type;
+
+	/* Initialize all the controls and registers */
+	InitTunerControls(fe);
+
+	/* Synthesizer LO frequency calculation */
+	MXL_SynthIFLO_Calc(fe);
+
+	return status;
+}
+
+static void MXL_SynthIFLO_Calc(struct dvb_frontend *fe)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	if (state->Mode == 1) /* Digital Mode */
+		state->IF_LO = state->IF_OUT;
+	else /* Analog Mode */ {
+		if (state->IF_Mode == 0) /* Analog Zero IF mode */
+			state->IF_LO = state->IF_OUT + 400000;
+		else /* Analog Low IF mode */
+			state->IF_LO = state->IF_OUT + state->Chan_Bandwidth/2;
+	}
+}
+
+static void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+
+	if (state->Mode == 1) /* Digital Mode */ {
+			/* remove 20.48MHz setting for 2.6.10 */
+			state->RF_LO = state->RF_IN;
+			/* change for 2.6.6 */
+			state->TG_LO = state->RF_IN - 750000;
+	} else /* Analog Mode */ {
+		if (state->IF_Mode == 0) /* Analog Zero IF mode */ {
+			state->RF_LO = state->RF_IN - 400000;
+			state->TG_LO = state->RF_IN - 1750000;
+		} else /* Analog Low IF mode */ {
+			state->RF_LO = state->RF_IN - state->Chan_Bandwidth/2;
+			state->TG_LO = state->RF_IN -
+				state->Chan_Bandwidth + 500000;
+		}
+	}
+}
+
+static u16 MXL_OverwriteICDefault(struct dvb_frontend *fe)
+{
+	u16 status = 0;
+
+	status += MXL_ControlWrite(fe, OVERRIDE_1, 1);
+	status += MXL_ControlWrite(fe, OVERRIDE_2, 1);
+	status += MXL_ControlWrite(fe, OVERRIDE_3, 1);
+	status += MXL_ControlWrite(fe, OVERRIDE_4, 1);
+
+	return status;
+}
+
+static u16 MXL_BlockInit(struct dvb_frontend *fe)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u16 status = 0;
+
+	status += MXL_OverwriteICDefault(fe);
+
+	/* Downconverter Control Dig Ana */
+	status += MXL_ControlWrite(fe, DN_IQTN_AMP_CUT, state->Mode ? 1 : 0);
+
+	/* Filter Control  Dig  Ana */
+	status += MXL_ControlWrite(fe, BB_MODE, state->Mode ? 0 : 1);
+	status += MXL_ControlWrite(fe, BB_BUF, state->Mode ? 3 : 2);
+	status += MXL_ControlWrite(fe, BB_BUF_OA, state->Mode ? 1 : 0);
+	status += MXL_ControlWrite(fe, BB_IQSWAP, state->Mode ? 0 : 1);
+	status += MXL_ControlWrite(fe, BB_INITSTATE_DLPF_TUNE, 0);
+
+	/* Initialize Low-Pass Filter */
+	if (state->Mode) { /* Digital Mode */
+		switch (state->Chan_Bandwidth) {
+		case 8000000:
+			status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 0);
+			break;
+		case 7000000:
+			status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 2);
+			break;
+		case 6000000:
+			status += MXL_ControlWrite(fe,
+					BB_DLPF_BANDSEL, 3);
+			break;
+		}
+	} else { /* Analog Mode */
+		switch (state->Chan_Bandwidth) {
+		case 8000000:	/* Low Zero */
+			status += MXL_ControlWrite(fe, BB_ALPF_BANDSELECT,
+					(state->IF_Mode ? 0 : 3));
+			break;
+		case 7000000:
+			status += MXL_ControlWrite(fe, BB_ALPF_BANDSELECT,
+					(state->IF_Mode ? 1 : 4));
+			break;
+		case 6000000:
+			status += MXL_ControlWrite(fe, BB_ALPF_BANDSELECT,
+					(state->IF_Mode ? 2 : 5));
+			break;
+		}
+	}
+
+	/* Charge Pump Control Dig  Ana */
+	status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, state->Mode ? 5 : 8);
+	status += MXL_ControlWrite(fe,
+		RFSYN_EN_CHP_HIGAIN, state->Mode ? 1 : 1);
+	status += MXL_ControlWrite(fe, EN_CHP_LIN_B, state->Mode ? 0 : 0);
+
+	/* AGC TOP Control */
+	if (state->AGC_Mode == 0) /* Dual AGC */ {
+		status += MXL_ControlWrite(fe, AGC_IF, 15);
+		status += MXL_ControlWrite(fe, AGC_RF, 15);
+	} else /*  Single AGC Mode Dig  Ana */
+		status += MXL_ControlWrite(fe, AGC_RF, state->Mode ? 15 : 12);
+
+	if (state->TOP == 55) /* TOP == 5.5 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0x0);
+
+	if (state->TOP == 72) /* TOP == 7.2 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0x1);
+
+	if (state->TOP == 92) /* TOP == 9.2 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0x2);
+
+	if (state->TOP == 110) /* TOP == 11.0 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0x3);
+
+	if (state->TOP == 129) /* TOP == 12.9 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0x4);
+
+	if (state->TOP == 147) /* TOP == 14.7 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0x5);
+
+	if (state->TOP == 168) /* TOP == 16.8 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0x6);
+
+	if (state->TOP == 194) /* TOP == 19.4 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0x7);
+
+	if (state->TOP == 212) /* TOP == 21.2 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0x9);
+
+	if (state->TOP == 232) /* TOP == 23.2 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0xA);
+
+	if (state->TOP == 252) /* TOP == 25.2 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0xB);
+
+	if (state->TOP == 271) /* TOP == 27.1 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0xC);
+
+	if (state->TOP == 292) /* TOP == 29.2 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0xD);
+
+	if (state->TOP == 317) /* TOP == 31.7 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0xE);
+
+	if (state->TOP == 349) /* TOP == 34.9 */
+		status += MXL_ControlWrite(fe, AGC_IF, 0xF);
+
+	/* IF Synthesizer Control */
+	status += MXL_IFSynthInit(fe);
+
+	/* IF UpConverter Control */
+	if (state->IF_OUT_LOAD == 200) {
+		status += MXL_ControlWrite(fe, DRV_RES_SEL, 6);
+		status += MXL_ControlWrite(fe, I_DRIVER, 2);
+	}
+	if (state->IF_OUT_LOAD == 300) {
+		status += MXL_ControlWrite(fe, DRV_RES_SEL, 4);
+		status += MXL_ControlWrite(fe, I_DRIVER, 1);
+	}
+
+	/* Anti-Alias Filtering Control
+	 * initialise Anti-Aliasing Filter
+	 */
+	if (state->Mode) { /* Digital Mode */
+		if (state->IF_OUT >= 4000000UL && state->IF_OUT <= 6280000UL) {
+			status += MXL_ControlWrite(fe, EN_AAF, 1);
+			status += MXL_ControlWrite(fe, EN_3P, 1);
+			status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
+			status += MXL_ControlWrite(fe, SEL_AAF_BAND, 0);
+		}
+		if ((state->IF_OUT == 36125000UL) ||
+			(state->IF_OUT == 36150000UL)) {
+			status += MXL_ControlWrite(fe, EN_AAF, 1);
+			status += MXL_ControlWrite(fe, EN_3P, 1);
+			status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
+			status += MXL_ControlWrite(fe, SEL_AAF_BAND, 1);
+		}
+		if (state->IF_OUT > 36150000UL) {
+			status += MXL_ControlWrite(fe, EN_AAF, 0);
+			status += MXL_ControlWrite(fe, EN_3P, 1);
+			status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
+			status += MXL_ControlWrite(fe, SEL_AAF_BAND, 1);
+		}
+	} else { /* Analog Mode */
+		if (state->IF_OUT >= 4000000UL && state->IF_OUT <= 5000000UL) {
+			status += MXL_ControlWrite(fe, EN_AAF, 1);
+			status += MXL_ControlWrite(fe, EN_3P, 1);
+			status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
+			status += MXL_ControlWrite(fe, SEL_AAF_BAND, 0);
+		}
+		if (state->IF_OUT > 5000000UL) {
+			status += MXL_ControlWrite(fe, EN_AAF, 0);
+			status += MXL_ControlWrite(fe, EN_3P, 0);
+			status += MXL_ControlWrite(fe, EN_AUX_3P, 0);
+			status += MXL_ControlWrite(fe, SEL_AAF_BAND, 0);
+		}
+	}
+
+	/* Demod Clock Out */
+	if (state->CLOCK_OUT)
+		status += MXL_ControlWrite(fe, SEQ_ENCLK16_CLK_OUT, 1);
+	else
+		status += MXL_ControlWrite(fe, SEQ_ENCLK16_CLK_OUT, 0);
+
+	if (state->DIV_OUT == 1)
+		status += MXL_ControlWrite(fe, SEQ_SEL4_16B, 1);
+	if (state->DIV_OUT == 0)
+		status += MXL_ControlWrite(fe, SEQ_SEL4_16B, 0);
+
+	/* Crystal Control */
+	if (state->CAPSELECT)
+		status += MXL_ControlWrite(fe, XTAL_CAPSELECT, 1);
+	else
+		status += MXL_ControlWrite(fe, XTAL_CAPSELECT, 0);
+
+	if (state->Fxtal >= 12000000UL && state->Fxtal <= 16000000UL)
+		status += MXL_ControlWrite(fe, IF_SEL_DBL, 1);
+	if (state->Fxtal > 16000000UL && state->Fxtal <= 32000000UL)
+		status += MXL_ControlWrite(fe, IF_SEL_DBL, 0);
+
+	if (state->Fxtal >= 12000000UL && state->Fxtal <= 22000000UL)
+		status += MXL_ControlWrite(fe, RFSYN_R_DIV, 3);
+	if (state->Fxtal > 22000000UL && state->Fxtal <= 32000000UL)
+		status += MXL_ControlWrite(fe, RFSYN_R_DIV, 0);
+
+	/* Misc Controls */
+	if (state->Mode == 0 && state->IF_Mode == 1) /* Analog LowIF mode */
+		status += MXL_ControlWrite(fe, SEQ_EXTIQFSMPULSE, 0);
+	else
+		status += MXL_ControlWrite(fe, SEQ_EXTIQFSMPULSE, 1);
+
+	/* status += MXL_ControlRead(fe, IF_DIVVAL, &IF_DIVVAL_Val); */
+
+	/* Set TG_R_DIV */
+	status += MXL_ControlWrite(fe, TG_R_DIV,
+		MXL_Ceiling(state->Fxtal, 1000000));
+
+	/* Apply Default value to BB_INITSTATE_DLPF_TUNE */
+
+	/* RSSI Control */
+	if (state->EN_RSSI) {
+		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
+		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+
+		/* RSSI reference point */
+		status += MXL_ControlWrite(fe, RFA_RSSI_REF, 2);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 3);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 1);
+
+		/* TOP point */
+		status += MXL_ControlWrite(fe, RFA_FLR, 0);
+		status += MXL_ControlWrite(fe, RFA_CEIL, 12);
+	}
+
+	/* Modulation type bit settings
+	 * Override the control values preset
+	 */
+	if (state->Mod_Type == MXL_DVBT) /* DVB-T Mode */ {
+		state->AGC_Mode = 1; /* Single AGC Mode */
+
+		/* Enable RSSI */
+		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
+		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+
+		/* RSSI reference point */
+		status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 1);
+
+		/* TOP point */
+		status += MXL_ControlWrite(fe, RFA_FLR, 2);
+		status += MXL_ControlWrite(fe, RFA_CEIL, 13);
+		if (state->IF_OUT <= 6280000UL)	/* Low IF */
+			status += MXL_ControlWrite(fe, BB_IQSWAP, 0);
+		else /* High IF */
+			status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
+
+	}
+	if (state->Mod_Type == MXL_ATSC) /* ATSC Mode */ {
+		state->AGC_Mode = 1;	/* Single AGC Mode */
+
+		/* Enable RSSI */
+		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
+		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+
+		/* RSSI reference point */
+		status += MXL_ControlWrite(fe, RFA_RSSI_REF, 2);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 4);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 1);
+
+		/* TOP point */
+		status += MXL_ControlWrite(fe, RFA_FLR, 2);
+		status += MXL_ControlWrite(fe, RFA_CEIL, 13);
+		status += MXL_ControlWrite(fe, BB_INITSTATE_DLPF_TUNE, 1);
+		/* Low Zero */
+		status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 5);
+
+		if (state->IF_OUT <= 6280000UL)	/* Low IF */
+			status += MXL_ControlWrite(fe, BB_IQSWAP, 0);
+		else /* High IF */
+			status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
+	}
+	if (state->Mod_Type == MXL_QAM) /* QAM Mode */ {
+		state->Mode = MXL_DIGITAL_MODE;
+
+		/* state->AGC_Mode = 1; */ /* Single AGC Mode */
+
+		/* Disable RSSI */	/* change here for v2.6.5 */
+		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
+		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+
+		/* RSSI reference point */
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 2);
+		/* change here for v2.6.5 */
+		status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
+
+		if (state->IF_OUT <= 6280000UL)	/* Low IF */
+			status += MXL_ControlWrite(fe, BB_IQSWAP, 0);
+		else /* High IF */
+			status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
+		status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2);
+
+	}
+	if (state->Mod_Type == MXL_ANALOG_CABLE) {
+		/* Analog Cable Mode */
+		/* state->Mode = MXL_DIGITAL_MODE; */
+
+		state->AGC_Mode = 1; /* Single AGC Mode */
+
+		/* Disable RSSI */
+		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
+		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+		/* change for 2.6.3 */
+		status += MXL_ControlWrite(fe, AGC_IF, 1);
+		status += MXL_ControlWrite(fe, AGC_RF, 15);
+		status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
+	}
+
+	if (state->Mod_Type == MXL_ANALOG_OTA) {
+		/* Analog OTA Terrestrial mode add for 2.6.7 */
+		/* state->Mode = MXL_ANALOG_MODE; */
+
+		/* Enable RSSI */
+		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
+		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+
+		/* RSSI reference point */
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
+		status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 2);
+		status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
+		status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
+	}
+
+	/* RSSI disable */
+	if (state->EN_RSSI == 0) {
+		status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+		status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
+		status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+	}
+
+	return status;
+}
+
+static u16 MXL_IFSynthInit(struct dvb_frontend *fe)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u16 status = 0 ;
+	u32	Fref = 0 ;
+	u32	Kdbl, intModVal ;
+	u32	fracModVal ;
+	Kdbl = 2 ;
+
+	if (state->Fxtal >= 12000000UL && state->Fxtal <= 16000000UL)
+		Kdbl = 2 ;
+	if (state->Fxtal > 16000000UL && state->Fxtal <= 32000000UL)
+		Kdbl = 1 ;
+
+	/* IF Synthesizer Control */
+	if (state->Mode == 0 && state->IF_Mode == 1) /* Analog Low IF mode */ {
+		if (state->IF_LO == 41000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+			Fref = 328000000UL ;
+		}
+		if (state->IF_LO == 47000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 376000000UL ;
+		}
+		if (state->IF_LO == 54000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x10);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+			Fref = 324000000UL ;
+		}
+		if (state->IF_LO == 60000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x10);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 360000000UL ;
+		}
+		if (state->IF_LO == 39250000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+			Fref = 314000000UL ;
+		}
+		if (state->IF_LO == 39650000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+			Fref = 317200000UL ;
+		}
+		if (state->IF_LO == 40150000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+			Fref = 321200000UL ;
+		}
+		if (state->IF_LO == 40650000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+			Fref = 325200000UL ;
+		}
+	}
+
+	if (state->Mode || (state->Mode == 0 && state->IF_Mode == 0)) {
+		if (state->IF_LO == 57000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x10);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 342000000UL ;
+		}
+		if (state->IF_LO == 44000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 352000000UL ;
+		}
+		if (state->IF_LO == 43750000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 350000000UL ;
+		}
+		if (state->IF_LO == 36650000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 366500000UL ;
+		}
+		if (state->IF_LO == 36150000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 361500000UL ;
+		}
+		if (state->IF_LO == 36000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 360000000UL ;
+		}
+		if (state->IF_LO == 35250000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 352500000UL ;
+		}
+		if (state->IF_LO == 34750000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 347500000UL ;
+		}
+		if (state->IF_LO == 6280000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x07);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 376800000UL ;
+		}
+		if (state->IF_LO == 5000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x09);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 360000000UL ;
+		}
+		if (state->IF_LO == 4500000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x06);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 360000000UL ;
+		}
+		if (state->IF_LO == 4570000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x06);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 365600000UL ;
+		}
+		if (state->IF_LO == 4000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x05);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 360000000UL ;
+		}
+		if (state->IF_LO == 57400000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x10);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 344400000UL ;
+		}
+		if (state->IF_LO == 44400000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 355200000UL ;
+		}
+		if (state->IF_LO == 44150000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x08);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 353200000UL ;
+		}
+		if (state->IF_LO == 37050000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 370500000UL ;
+		}
+		if (state->IF_LO == 36550000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 365500000UL ;
+		}
+		if (state->IF_LO == 36125000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x04);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 361250000UL ;
+		}
+		if (state->IF_LO == 6000000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x07);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 360000000UL ;
+		}
+		if (state->IF_LO == 5400000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x07);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+			Fref = 324000000UL ;
+		}
+		if (state->IF_LO == 5380000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x07);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+			Fref = 322800000UL ;
+		}
+		if (state->IF_LO == 5200000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x09);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 374400000UL ;
+		}
+		if (state->IF_LO == 4900000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x09);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 352800000UL ;
+		}
+		if (state->IF_LO == 4400000UL) {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x06);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 352000000UL ;
+		}
+		if (state->IF_LO == 4063000UL)  /* add for 2.6.8 */ {
+			status += MXL_ControlWrite(fe, IF_DIVVAL,   0x05);
+			status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+			Fref = 365670000UL ;
+		}
+	}
+	/* CHCAL_INT_MOD_IF */
+	/* CHCAL_FRAC_MOD_IF */
+	intModVal = Fref / (state->Fxtal * Kdbl/2);
+	status += MXL_ControlWrite(fe, CHCAL_INT_MOD_IF, intModVal);
+
+	fracModVal = (2<<15)*(Fref/1000 - (state->Fxtal/1000 * Kdbl/2) *
+		intModVal);
+
+	fracModVal = fracModVal / ((state->Fxtal * Kdbl/2)/1000);
+	status += MXL_ControlWrite(fe, CHCAL_FRAC_MOD_IF, fracModVal);
+
+	return status ;
+}
+
+static u32 MXL_GetXtalInt(u32 Xtal_Freq)
+{
+	if ((Xtal_Freq % 1000000) == 0)
+		return (Xtal_Freq / 10000);
+	else
+		return (((Xtal_Freq / 1000000) + 1)*100);
+}
+
+static u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u16 status = 0;
+	u32 divider_val, E3, E4, E5, E5A;
+	u32 Fmax, Fmin, FmaxBin, FminBin;
+	u32 Kdbl_RF = 2;
+	u32 tg_divval;
+	u32 tg_lo;
+	u32 Xtal_Int;
+
+	u32 Fref_TG;
+	u32 Fvco;
+
+	Xtal_Int = MXL_GetXtalInt(state->Fxtal);
+
+	state->RF_IN = RF_Freq;
+
+	MXL_SynthRFTGLO_Calc(fe);
+
+	if (state->Fxtal >= 12000000UL && state->Fxtal <= 22000000UL)
+		Kdbl_RF = 2;
+	if (state->Fxtal > 22000000 && state->Fxtal <= 32000000)
+		Kdbl_RF = 1;
+
+	/* Downconverter Controls
+	 * Look-Up Table Implementation for:
+	 *	DN_POLY
+	 *	DN_RFGAIN
+	 *	DN_CAP_RFLPF
+	 *	DN_EN_VHFUHFBAR
+	 *	DN_GAIN_ADJUST
+	 *  Change the boundary reference from RF_IN to RF_LO
+	 */
+	if (state->RF_LO < 40000000UL)
+		return -1;
+
+	if (state->RF_LO >= 40000000UL && state->RF_LO <= 75000000UL) {
+		status += MXL_ControlWrite(fe, DN_POLY,              2);
+		status += MXL_ControlWrite(fe, DN_RFGAIN,            3);
+		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         423);
+		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      1);
+		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       1);
+	}
+	if (state->RF_LO > 75000000UL && state->RF_LO <= 100000000UL) {
+		status += MXL_ControlWrite(fe, DN_POLY,              3);
+		status += MXL_ControlWrite(fe, DN_RFGAIN,            3);
+		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         222);
+		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      1);
+		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       1);
+	}
+	if (state->RF_LO > 100000000UL && state->RF_LO <= 150000000UL) {
+		status += MXL_ControlWrite(fe, DN_POLY,              3);
+		status += MXL_ControlWrite(fe, DN_RFGAIN,            3);
+		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         147);
+		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      1);
+		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       2);
+	}
+	if (state->RF_LO > 150000000UL && state->RF_LO <= 200000000UL) {
+		status += MXL_ControlWrite(fe, DN_POLY,              3);
+		status += MXL_ControlWrite(fe, DN_RFGAIN,            3);
+		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         9);
+		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      1);
+		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       2);
+	}
+	if (state->RF_LO > 200000000UL && state->RF_LO <= 300000000UL) {
+		status += MXL_ControlWrite(fe, DN_POLY,              3);
+		status += MXL_ControlWrite(fe, DN_RFGAIN,            3);
+		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         0);
+		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      1);
+		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       3);
+	}
+	if (state->RF_LO > 300000000UL && state->RF_LO <= 650000000UL) {
+		status += MXL_ControlWrite(fe, DN_POLY,              3);
+		status += MXL_ControlWrite(fe, DN_RFGAIN,            1);
+		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         0);
+		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      0);
+		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       3);
+	}
+	if (state->RF_LO > 650000000UL && state->RF_LO <= 900000000UL) {
+		status += MXL_ControlWrite(fe, DN_POLY,              3);
+		status += MXL_ControlWrite(fe, DN_RFGAIN,            2);
+		status += MXL_ControlWrite(fe, DN_CAP_RFLPF,         0);
+		status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR,      0);
+		status += MXL_ControlWrite(fe, DN_GAIN_ADJUST,       3);
+	}
+	if (state->RF_LO > 900000000UL)
+		return -1;
+
+	/*	DN_IQTNBUF_AMP */
+	/*	DN_IQTNGNBFBIAS_BST */
+	if (state->RF_LO >= 40000000UL && state->RF_LO <= 75000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 75000000UL && state->RF_LO <= 100000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 100000000UL && state->RF_LO <= 150000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 150000000UL && state->RF_LO <= 200000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 200000000UL && state->RF_LO <= 300000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 300000000UL && state->RF_LO <= 400000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 400000000UL && state->RF_LO <= 450000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 450000000UL && state->RF_LO <= 500000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 500000000UL && state->RF_LO <= 550000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 550000000UL && state->RF_LO <= 600000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 600000000UL && state->RF_LO <= 650000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 650000000UL && state->RF_LO <= 700000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 700000000UL && state->RF_LO <= 750000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 750000000UL && state->RF_LO <= 800000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       1);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  0);
+	}
+	if (state->RF_LO > 800000000UL && state->RF_LO <= 850000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       10);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  1);
+	}
+	if (state->RF_LO > 850000000UL && state->RF_LO <= 900000000UL) {
+		status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP,       10);
+		status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST,  1);
+	}
+
+	/*
+	 * Set RF Synth and LO Path Control
+	 *
+	 * Look-Up table implementation for:
+	 *	RFSYN_EN_OUTMUX
+	 *	RFSYN_SEL_VCO_OUT
+	 *	RFSYN_SEL_VCO_HI
+	 *  RFSYN_SEL_DIVM
+	 *	RFSYN_RF_DIV_BIAS
+	 *	DN_SEL_FREQ
+	 *
+	 * Set divider_val, Fmax, Fmix to use in Equations
+	 */
+	FminBin = 28000000UL ;
+	FmaxBin = 42500000UL ;
+	if (state->RF_LO >= 40000000UL && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         1);
+		divider_val = 64 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 42500000UL ;
+	FmaxBin = 56000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         1);
+		divider_val = 64 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 56000000UL ;
+	FmaxBin = 85000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         1);
+		divider_val = 32 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 85000000UL ;
+	FmaxBin = 112000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         1);
+		divider_val = 32 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 112000000UL ;
+	FmaxBin = 170000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         2);
+		divider_val = 16 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 170000000UL ;
+	FmaxBin = 225000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         2);
+		divider_val = 16 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 225000000UL ;
+	FmaxBin = 300000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         4);
+		divider_val = 8 ;
+		Fmax = 340000000UL ;
+		Fmin = FminBin ;
+	}
+	FminBin = 300000000UL ;
+	FmaxBin = 340000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         0);
+		divider_val = 8 ;
+		Fmax = FmaxBin ;
+		Fmin = 225000000UL ;
+	}
+	FminBin = 340000000UL ;
+	FmaxBin = 450000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      0);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   2);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         0);
+		divider_val = 8 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 450000000UL ;
+	FmaxBin = 680000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      1);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         0);
+		divider_val = 4 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 680000000UL ;
+	FmaxBin = 900000000UL ;
+	if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX,     0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT,   1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI,    1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM,      1);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS,   1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ,         0);
+		divider_val = 4 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+
+	/*	CHCAL_INT_MOD_RF
+	 *	CHCAL_FRAC_MOD_RF
+	 *	RFSYN_LPF_R
+	 *	CHCAL_EN_INT_RF
+	 */
+	/* Equation E3 RFSYN_VCO_BIAS */
+	E3 = (((Fmax-state->RF_LO)/1000)*32)/((Fmax-Fmin)/1000) + 8 ;
+	status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, E3);
+
+	/* Equation E4 CHCAL_INT_MOD_RF */
+	E4 = (state->RF_LO*divider_val/1000)/(2*state->Fxtal*Kdbl_RF/1000);
+	MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, E4);
+
+	/* Equation E5 CHCAL_FRAC_MOD_RF CHCAL_EN_INT_RF */
+	E5 = ((2<<17)*(state->RF_LO/10000*divider_val -
+		(E4*(2*state->Fxtal*Kdbl_RF)/10000))) /
+		(2*state->Fxtal*Kdbl_RF/10000);
+
+	status += MXL_ControlWrite(fe, CHCAL_FRAC_MOD_RF, E5);
+
+	/* Equation E5A RFSYN_LPF_R */
+	E5A = (((Fmax - state->RF_LO)/1000)*4/((Fmax-Fmin)/1000)) + 1 ;
+	status += MXL_ControlWrite(fe, RFSYN_LPF_R, E5A);
+
+	/* Euqation E5B CHCAL_EN_INIT_RF */
+	status += MXL_ControlWrite(fe, CHCAL_EN_INT_RF, ((E5 == 0) ? 1 : 0));
+	/*if (E5 == 0)
+	 *	status += MXL_ControlWrite(fe, CHCAL_EN_INT_RF, 1);
+	 *else
+	 *	status += MXL_ControlWrite(fe, CHCAL_FRAC_MOD_RF, E5);
+	 */
+
+	/*
+	 * Set TG Synth
+	 *
+	 * Look-Up table implementation for:
+	 *	TG_LO_DIVVAL
+	 *	TG_LO_SELVAL
+	 *
+	 * Set divider_val, Fmax, Fmix to use in Equations
+	 */
+	if (state->TG_LO < 33000000UL)
+		return -1;
+
+	FminBin = 33000000UL ;
+	FmaxBin = 50000000UL ;
+	if (state->TG_LO >= FminBin && state->TG_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x6);
+		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x0);
+		divider_val = 36 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 50000000UL ;
+	FmaxBin = 67000000UL ;
+	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x1);
+		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x0);
+		divider_val = 24 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 67000000UL ;
+	FmaxBin = 100000000UL ;
+	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0xC);
+		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x2);
+		divider_val = 18 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 100000000UL ;
+	FmaxBin = 150000000UL ;
+	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x8);
+		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x2);
+		divider_val = 12 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 150000000UL ;
+	FmaxBin = 200000000UL ;
+	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x0);
+		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x2);
+		divider_val = 8 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 200000000UL ;
+	FmaxBin = 300000000UL ;
+	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x8);
+		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x3);
+		divider_val = 6 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 300000000UL ;
+	FmaxBin = 400000000UL ;
+	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x0);
+		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x3);
+		divider_val = 4 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 400000000UL ;
+	FmaxBin = 600000000UL ;
+	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x8);
+		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x7);
+		divider_val = 3 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+	FminBin = 600000000UL ;
+	FmaxBin = 900000000UL ;
+	if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+		status += MXL_ControlWrite(fe, TG_LO_DIVVAL,	0x0);
+		status += MXL_ControlWrite(fe, TG_LO_SELVAL,	0x7);
+		divider_val = 2 ;
+		Fmax = FmaxBin ;
+		Fmin = FminBin ;
+	}
+
+	/* TG_DIV_VAL */
+	tg_divval = (state->TG_LO*divider_val/100000) *
+		(MXL_Ceiling(state->Fxtal, 1000000) * 100) /
+		(state->Fxtal/1000);
+
+	status += MXL_ControlWrite(fe, TG_DIV_VAL, tg_divval);
+
+	if (state->TG_LO > 600000000UL)
+		status += MXL_ControlWrite(fe, TG_DIV_VAL, tg_divval + 1);
+
+	Fmax = 1800000000UL ;
+	Fmin = 1200000000UL ;
+
+	/* prevent overflow of 32 bit unsigned integer, use
+	 * following equation. Edit for v2.6.4
+	 */
+	/* Fref_TF = Fref_TG * 1000 */
+	Fref_TG = (state->Fxtal/1000) / MXL_Ceiling(state->Fxtal, 1000000);
+
+	/* Fvco = Fvco/10 */
+	Fvco = (state->TG_LO/10000) * divider_val * Fref_TG;
+
+	tg_lo = (((Fmax/10 - Fvco)/100)*32) / ((Fmax-Fmin)/1000)+8;
+
+	/* below equation is same as above but much harder to debug.
+	 * tg_lo = ( ((Fmax/10000 * Xtal_Int)/100) -
+	 * ((state->TG_LO/10000)*divider_val *
+	 * (state->Fxtal/10000)/100) )*32/((Fmax-Fmin)/10000 *
+	 * Xtal_Int/100) + 8;
+	 */
+
+	status += MXL_ControlWrite(fe, TG_VCO_BIAS , tg_lo);
+
+	/* add for 2.6.5 Special setting for QAM */
+	if (state->Mod_Type == MXL_QAM) {
+		if (state->RF_IN < 680000000)
+			status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
+		else
+			status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2);
+	}
+
+	/* Off Chip Tracking Filter Control */
+	if (state->TF_Type == MXL_TF_OFF) {
+		/* Tracking Filter Off State; turn off all the banks */
+		status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+		status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+		status += MXL_SetGPIO(fe, 3, 1); /* Bank1 Off */
+		status += MXL_SetGPIO(fe, 1, 1); /* Bank2 Off */
+		status += MXL_SetGPIO(fe, 4, 1); /* Bank3 Off */
+	}
+
+	if (state->TF_Type == MXL_TF_C) /* Tracking Filter type C */ {
+		status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+		status += MXL_ControlWrite(fe, DAC_DIN_A, 0);
+
+		if (state->RF_IN >= 43000000 && state->RF_IN < 150000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+			status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+			status += MXL_SetGPIO(fe, 3, 0);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+		}
+		if (state->RF_IN >= 150000000 && state->RF_IN < 280000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+			status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+		}
+		if (state->RF_IN >= 280000000 && state->RF_IN < 360000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+			status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+		}
+		if (state->RF_IN >= 360000000 && state->RF_IN < 560000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+			status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 4, 0);
+		}
+		if (state->RF_IN >= 560000000 && state->RF_IN < 580000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_ControlWrite(fe, DAC_DIN_B, 29);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 4, 0);
+		}
+		if (state->RF_IN >= 580000000 && state->RF_IN < 630000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 4, 0);
+		}
+		if (state->RF_IN >= 630000000 && state->RF_IN < 700000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_ControlWrite(fe, DAC_DIN_B, 16);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+		}
+		if (state->RF_IN >= 700000000 && state->RF_IN < 760000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_ControlWrite(fe, DAC_DIN_B, 7);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+		}
+		if (state->RF_IN >= 760000000 && state->RF_IN <= 900000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+		}
+	}
+
+	if (state->TF_Type == MXL_TF_C_H) {
+
+		/* Tracking Filter type C-H for Hauppauge only */
+		status += MXL_ControlWrite(fe, DAC_DIN_A, 0);
+
+		if (state->RF_IN >= 43000000 && state->RF_IN < 150000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+		}
+		if (state->RF_IN >= 150000000 && state->RF_IN < 280000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+			status += MXL_SetGPIO(fe, 1, 1);
+		}
+		if (state->RF_IN >= 280000000 && state->RF_IN < 360000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+			status += MXL_SetGPIO(fe, 1, 0);
+		}
+		if (state->RF_IN >= 360000000 && state->RF_IN < 560000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+		}
+		if (state->RF_IN >= 560000000 && state->RF_IN < 580000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+		}
+		if (state->RF_IN >= 580000000 && state->RF_IN < 630000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+		}
+		if (state->RF_IN >= 630000000 && state->RF_IN < 700000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+		}
+		if (state->RF_IN >= 700000000 && state->RF_IN < 760000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+		}
+		if (state->RF_IN >= 760000000 && state->RF_IN <= 900000000) {
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+		}
+	}
+
+	if (state->TF_Type == MXL_TF_D) { /* Tracking Filter type D */
+
+		status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+
+		if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 250000000 && state->RF_IN < 310000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 310000000 && state->RF_IN < 360000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 360000000 && state->RF_IN < 470000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 470000000 && state->RF_IN < 640000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 640000000 && state->RF_IN <= 900000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+	}
+
+	if (state->TF_Type == MXL_TF_D_L) {
+
+		/* Tracking Filter type D-L for Lumanate ONLY change 2.6.3 */
+		status += MXL_ControlWrite(fe, DAC_DIN_A, 0);
+
+		/* if UHF and terrestrial => Turn off Tracking Filter */
+		if (state->RF_IN >= 471000000 &&
+			(state->RF_IN - 471000000)%6000000 != 0) {
+			/* Turn off all the banks */
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+			status += MXL_ControlWrite(fe, AGC_IF, 10);
+		} else {
+			/* if VHF or cable => Turn on Tracking Filter */
+			if (state->RF_IN >= 43000000 &&
+				state->RF_IN < 140000000) {
+
+				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+				status += MXL_SetGPIO(fe, 4, 1);
+				status += MXL_SetGPIO(fe, 1, 1);
+				status += MXL_SetGPIO(fe, 3, 0);
+			}
+			if (state->RF_IN >= 140000000 &&
+				state->RF_IN < 240000000) {
+				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+				status += MXL_SetGPIO(fe, 4, 1);
+				status += MXL_SetGPIO(fe, 1, 0);
+				status += MXL_SetGPIO(fe, 3, 0);
+			}
+			if (state->RF_IN >= 240000000 &&
+				state->RF_IN < 340000000) {
+				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+				status += MXL_SetGPIO(fe, 4, 0);
+				status += MXL_SetGPIO(fe, 1, 1);
+				status += MXL_SetGPIO(fe, 3, 0);
+			}
+			if (state->RF_IN >= 340000000 &&
+				state->RF_IN < 430000000) {
+				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+				status += MXL_SetGPIO(fe, 4, 0);
+				status += MXL_SetGPIO(fe, 1, 0);
+				status += MXL_SetGPIO(fe, 3, 1);
+			}
+			if (state->RF_IN >= 430000000 &&
+				state->RF_IN < 470000000) {
+				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+				status += MXL_SetGPIO(fe, 4, 1);
+				status += MXL_SetGPIO(fe, 1, 0);
+				status += MXL_SetGPIO(fe, 3, 1);
+			}
+			if (state->RF_IN >= 470000000 &&
+				state->RF_IN < 570000000) {
+				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+				status += MXL_SetGPIO(fe, 4, 0);
+				status += MXL_SetGPIO(fe, 1, 0);
+				status += MXL_SetGPIO(fe, 3, 1);
+			}
+			if (state->RF_IN >= 570000000 &&
+				state->RF_IN < 620000000) {
+				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+				status += MXL_SetGPIO(fe, 4, 0);
+				status += MXL_SetGPIO(fe, 1, 1);
+				status += MXL_SetGPIO(fe, 3, 1);
+			}
+			if (state->RF_IN >= 620000000 &&
+				state->RF_IN < 760000000) {
+				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+				status += MXL_SetGPIO(fe, 4, 0);
+				status += MXL_SetGPIO(fe, 1, 1);
+				status += MXL_SetGPIO(fe, 3, 1);
+			}
+			if (state->RF_IN >= 760000000 &&
+				state->RF_IN <= 900000000) {
+				status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+				status += MXL_SetGPIO(fe, 4, 1);
+				status += MXL_SetGPIO(fe, 1, 1);
+				status += MXL_SetGPIO(fe, 3, 1);
+			}
+		}
+	}
+
+	if (state->TF_Type == MXL_TF_E) /* Tracking Filter type E */ {
+
+		status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+
+		if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 250000000 && state->RF_IN < 310000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 310000000 && state->RF_IN < 360000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 360000000 && state->RF_IN < 470000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 470000000 && state->RF_IN < 640000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 640000000 && state->RF_IN <= 900000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+	}
+
+	if (state->TF_Type == MXL_TF_F) {
+
+		/* Tracking Filter type F */
+		status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+
+		if (state->RF_IN >= 43000000 && state->RF_IN < 160000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 160000000 && state->RF_IN < 210000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 210000000 && state->RF_IN < 300000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 300000000 && state->RF_IN < 390000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 390000000 && state->RF_IN < 515000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 515000000 && state->RF_IN < 650000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 650000000 && state->RF_IN <= 900000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+	}
+
+	if (state->TF_Type == MXL_TF_E_2) {
+
+		/* Tracking Filter type E_2 */
+		status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+
+		if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 250000000 && state->RF_IN < 350000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 350000000 && state->RF_IN < 400000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 400000000 && state->RF_IN < 570000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 570000000 && state->RF_IN < 770000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 770000000 && state->RF_IN <= 900000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+	}
+
+	if (state->TF_Type == MXL_TF_G) {
+
+		/* Tracking Filter type G add for v2.6.8 */
+		status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+
+		if (state->RF_IN >= 50000000 && state->RF_IN < 190000000) {
+
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 190000000 && state->RF_IN < 280000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 280000000 && state->RF_IN < 350000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 350000000 && state->RF_IN < 400000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 400000000 && state->RF_IN < 470000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 470000000 && state->RF_IN < 640000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 640000000 && state->RF_IN < 820000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 820000000 && state->RF_IN <= 900000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+	}
+
+	if (state->TF_Type == MXL_TF_E_NA) {
+
+		/* Tracking Filter type E-NA for Empia ONLY change for 2.6.8 */
+		status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+
+		/* if UHF and terrestrial=> Turn off Tracking Filter */
+		if (state->RF_IN >= 471000000 &&
+			(state->RF_IN - 471000000)%6000000 != 0) {
+
+			/* Turn off all the banks */
+			status += MXL_SetGPIO(fe, 3, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+
+			/* 2.6.12 Turn on RSSI */
+			status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+			status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+			status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
+			status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+
+			/* RSSI reference point */
+			status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
+			status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
+			status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 2);
+
+			/* following parameter is from analog OTA mode,
+			 * can be change to seek better performance */
+			status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
+		} else {
+		/* if VHF or Cable =>  Turn on Tracking Filter */
+
+		/* 2.6.12 Turn off RSSI */
+		status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
+
+		/* change back from above condition */
+		status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 5);
+
+
+		if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
+
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 0);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 250000000 && state->RF_IN < 350000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		if (state->RF_IN >= 350000000 && state->RF_IN < 400000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 0);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 400000000 && state->RF_IN < 570000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 570000000 && state->RF_IN < 770000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 0);
+		}
+		if (state->RF_IN >= 770000000 && state->RF_IN <= 900000000) {
+			status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+			status += MXL_SetGPIO(fe, 4, 1);
+			status += MXL_SetGPIO(fe, 1, 1);
+			status += MXL_SetGPIO(fe, 3, 1);
+		}
+		}
+	}
+	return status ;
+}
+
+static u16 MXL_SetGPIO(struct dvb_frontend *fe, u8 GPIO_Num, u8 GPIO_Val)
+{
+	u16 status = 0;
+
+	if (GPIO_Num == 1)
+		status += MXL_ControlWrite(fe, GPIO_1B, GPIO_Val ? 0 : 1);
+
+	/* GPIO2 is not available */
+
+	if (GPIO_Num == 3) {
+		if (GPIO_Val == 1) {
+			status += MXL_ControlWrite(fe, GPIO_3, 0);
+			status += MXL_ControlWrite(fe, GPIO_3B, 0);
+		}
+		if (GPIO_Val == 0) {
+			status += MXL_ControlWrite(fe, GPIO_3, 1);
+			status += MXL_ControlWrite(fe, GPIO_3B, 1);
+		}
+		if (GPIO_Val == 3) { /* tri-state */
+			status += MXL_ControlWrite(fe, GPIO_3, 0);
+			status += MXL_ControlWrite(fe, GPIO_3B, 1);
+		}
+	}
+	if (GPIO_Num == 4) {
+		if (GPIO_Val == 1) {
+			status += MXL_ControlWrite(fe, GPIO_4, 0);
+			status += MXL_ControlWrite(fe, GPIO_4B, 0);
+		}
+		if (GPIO_Val == 0) {
+			status += MXL_ControlWrite(fe, GPIO_4, 1);
+			status += MXL_ControlWrite(fe, GPIO_4B, 1);
+		}
+		if (GPIO_Val == 3) { /* tri-state */
+			status += MXL_ControlWrite(fe, GPIO_4, 0);
+			status += MXL_ControlWrite(fe, GPIO_4B, 1);
+		}
+	}
+
+	return status;
+}
+
+static u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value)
+{
+	u16 status = 0;
+
+	/* Will write ALL Matching Control Name */
+	/* Write Matching INIT Control */
+	status += MXL_ControlWrite_Group(fe, ControlNum, value, 1);
+	/* Write Matching CH Control */
+	status += MXL_ControlWrite_Group(fe, ControlNum, value, 2);
+#ifdef _MXL_INTERNAL
+	/* Write Matching MXL Control */
+	status += MXL_ControlWrite_Group(fe, ControlNum, value, 3);
+#endif
+	return status;
+}
+
+static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum,
+	u32 value, u16 controlGroup)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u16 i, j, k;
+	u32 highLimit;
+	u32 ctrlVal;
+
+	if (controlGroup == 1) /* Initial Control */ {
+
+		for (i = 0; i < state->Init_Ctrl_Num; i++) {
+
+			if (controlNum == state->Init_Ctrl[i].Ctrl_Num) {
+
+				highLimit = 1 << state->Init_Ctrl[i].size;
+				if (value < highLimit) {
+					for (j = 0; j < state->Init_Ctrl[i].size; j++) {
+						state->Init_Ctrl[i].val[j] = (u8)((value >> j) & 0x01);
+						MXL_RegWriteBit(fe, (u8)(state->Init_Ctrl[i].addr[j]),
+							(u8)(state->Init_Ctrl[i].bit[j]),
+							(u8)((value>>j) & 0x01));
+					}
+					ctrlVal = 0;
+					for (k = 0; k < state->Init_Ctrl[i].size; k++)
+						ctrlVal += state->Init_Ctrl[i].val[k] * (1 << k);
+				} else
+					return -1;
+			}
+		}
+	}
+	if (controlGroup == 2) /* Chan change Control */ {
+
+		for (i = 0; i < state->CH_Ctrl_Num; i++) {
+
+			if (controlNum == state->CH_Ctrl[i].Ctrl_Num) {
+
+				highLimit = 1 << state->CH_Ctrl[i].size;
+				if (value < highLimit) {
+					for (j = 0; j < state->CH_Ctrl[i].size; j++) {
+						state->CH_Ctrl[i].val[j] = (u8)((value >> j) & 0x01);
+						MXL_RegWriteBit(fe, (u8)(state->CH_Ctrl[i].addr[j]),
+							(u8)(state->CH_Ctrl[i].bit[j]),
+							(u8)((value>>j) & 0x01));
+					}
+					ctrlVal = 0;
+					for (k = 0; k < state->CH_Ctrl[i].size; k++)
+						ctrlVal += state->CH_Ctrl[i].val[k] * (1 << k);
+				} else
+					return -1;
+			}
+		}
+	}
+#ifdef _MXL_INTERNAL
+	if (controlGroup == 3) /* Maxlinear Control */ {
+
+		for (i = 0; i < state->MXL_Ctrl_Num; i++) {
+
+			if (controlNum == state->MXL_Ctrl[i].Ctrl_Num) {
+
+				highLimit = (1 << state->MXL_Ctrl[i].size);
+				if (value < highLimit) {
+					for (j = 0; j < state->MXL_Ctrl[i].size; j++) {
+						state->MXL_Ctrl[i].val[j] = (u8)((value >> j) & 0x01);
+						MXL_RegWriteBit(fe, (u8)(state->MXL_Ctrl[i].addr[j]),
+							(u8)(state->MXL_Ctrl[i].bit[j]),
+							(u8)((value>>j) & 0x01));
+					}
+					ctrlVal = 0;
+					for (k = 0; k < state->MXL_Ctrl[i].size; k++)
+						ctrlVal += state->MXL_Ctrl[i].val[k] * (1 << k);
+				} else
+					return -1;
+			}
+		}
+	}
+#endif
+	return 0 ; /* successful return */
+}
+
+static u16 MXL_RegRead(struct dvb_frontend *fe, u8 RegNum, u8 *RegVal)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	int i ;
+
+	for (i = 0; i < 104; i++) {
+		if (RegNum == state->TunerRegs[i].Reg_Num) {
+			*RegVal = (u8)(state->TunerRegs[i].Reg_Val);
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+static u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u32 ctrlVal ;
+	u16 i, k ;
+
+	for (i = 0; i < state->Init_Ctrl_Num ; i++) {
+
+		if (controlNum == state->Init_Ctrl[i].Ctrl_Num) {
+
+			ctrlVal = 0;
+			for (k = 0; k < state->Init_Ctrl[i].size; k++)
+				ctrlVal += state->Init_Ctrl[i].val[k] * (1<<k);
+			*value = ctrlVal;
+			return 0;
+		}
+	}
+
+	for (i = 0; i < state->CH_Ctrl_Num ; i++) {
+
+		if (controlNum == state->CH_Ctrl[i].Ctrl_Num) {
+
+			ctrlVal = 0;
+			for (k = 0; k < state->CH_Ctrl[i].size; k++)
+				ctrlVal += state->CH_Ctrl[i].val[k] * (1 << k);
+			*value = ctrlVal;
+			return 0;
+
+		}
+	}
+
+#ifdef _MXL_INTERNAL
+	for (i = 0; i < state->MXL_Ctrl_Num ; i++) {
+
+		if (controlNum == state->MXL_Ctrl[i].Ctrl_Num) {
+
+			ctrlVal = 0;
+			for (k = 0; k < state->MXL_Ctrl[i].size; k++)
+				ctrlVal += state->MXL_Ctrl[i].val[k] * (1<<k);
+			*value = ctrlVal;
+			return 0;
+
+		}
+	}
+#endif
+	return 1;
+}
+
+static void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit,
+	u8 bitVal)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	int i ;
+
+	const u8 AND_MAP[8] = {
+		0xFE, 0xFD, 0xFB, 0xF7,
+		0xEF, 0xDF, 0xBF, 0x7F } ;
+
+	const u8 OR_MAP[8] = {
+		0x01, 0x02, 0x04, 0x08,
+		0x10, 0x20, 0x40, 0x80 } ;
+
+	for (i = 0; i < state->TunerRegs_Num; i++) {
+		if (state->TunerRegs[i].Reg_Num == address) {
+			if (bitVal)
+				state->TunerRegs[i].Reg_Val |= OR_MAP[bit];
+			else
+				state->TunerRegs[i].Reg_Val &= AND_MAP[bit];
+			break ;
+		}
+	}
+}
+
+static u32 MXL_Ceiling(u32 value, u32 resolution)
+{
+	return (value/resolution + (value % resolution > 0 ? 1 : 0));
+}
+
+/* Retrieve the Initialzation Registers */
+static u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 *RegNum,
+	u8 *RegVal, int *count)
+{
+	u16 status = 0;
+	int i ;
+
+	u8 RegAddr[] = {
+		11, 12, 13, 22, 32, 43, 44, 53, 56, 59, 73,
+		76, 77, 91, 134, 135, 137, 147,
+		156, 166, 167, 168, 25 };
+
+	*count = sizeof(RegAddr) / sizeof(u8);
+
+	status += MXL_BlockInit(fe);
+
+	for (i = 0 ; i < *count; i++) {
+		RegNum[i] = RegAddr[i];
+		status += MXL_RegRead(fe, RegNum[i], &RegVal[i]);
+	}
+
+	return status;
+}
+
+static u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 *RegNum, u8 *RegVal,
+	int *count)
+{
+	u16 status = 0;
+	int i ;
+
+/* add 77, 166, 167, 168 register for 2.6.12 */
+#ifdef _MXL_PRODUCTION
+	u8 RegAddr[] = {14, 15, 16, 17, 22, 43, 65, 68, 69, 70, 73, 92, 93, 106,
+	   107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168 } ;
+#else
+	u8 RegAddr[] = {14, 15, 16, 17, 22, 43, 68, 69, 70, 73, 92, 93, 106,
+	   107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168 } ;
+	/*
+	u8 RegAddr[171];
+	for (i = 0; i <= 170; i++)
+		RegAddr[i] = i;
+	*/
+#endif
+
+	*count = sizeof(RegAddr) / sizeof(u8);
+
+	for (i = 0 ; i < *count; i++) {
+		RegNum[i] = RegAddr[i];
+		status += MXL_RegRead(fe, RegNum[i], &RegVal[i]);
+	}
+
+	return status;
+}
+
+static u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 *RegNum,
+	u8 *RegVal, int *count)
+{
+	u16 status = 0;
+	int i;
+
+	u8 RegAddr[] = {43, 136};
+
+	*count = sizeof(RegAddr) / sizeof(u8);
+
+	for (i = 0; i < *count; i++) {
+		RegNum[i] = RegAddr[i];
+		status += MXL_RegRead(fe, RegNum[i], &RegVal[i]);
+	}
+
+	return status;
+}
+
+static u16 MXL_GetMasterControl(u8 *MasterReg, int state)
+{
+	if (state == 1) /* Load_Start */
+		*MasterReg = 0xF3;
+	if (state == 2) /* Power_Down */
+		*MasterReg = 0x41;
+	if (state == 3) /* Synth_Reset */
+		*MasterReg = 0xB1;
+	if (state == 4) /* Seq_Off */
+		*MasterReg = 0xF1;
+
+	return 0;
+}
+
+#ifdef _MXL_PRODUCTION
+static u16 MXL_VCORange_Test(struct dvb_frontend *fe, int VCO_Range)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u16 status = 0 ;
+
+	if (VCO_Range == 1) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+		status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
+		if (state->Mode == 0 && state->IF_Mode == 1) {
+			/* Analog Low IF Mode */
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 56);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 180224);
+		}
+		if (state->Mode == 0 && state->IF_Mode == 0) {
+			/* Analog Zero IF Mode */
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 56);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 222822);
+		}
+		if (state->Mode == 1) /* Digital Mode */ {
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 56);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 229376);
+		}
+	}
+
+	if (VCO_Range == 2) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+		status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+		status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+		status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 41);
+		if (state->Mode == 0 && state->IF_Mode == 1) {
+			/* Analog Low IF Mode */
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 206438);
+		}
+		if (state->Mode == 0 && state->IF_Mode == 0) {
+			/* Analog Zero IF Mode */
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 206438);
+		}
+		if (state->Mode == 1) /* Digital Mode */ {
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 41);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 16384);
+		}
+	}
+
+	if (VCO_Range == 3) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+		status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+		status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+		status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
+		if (state->Mode == 0 && state->IF_Mode == 1) {
+			/* Analog Low IF Mode */
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 44);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 173670);
+		}
+		if (state->Mode == 0 && state->IF_Mode == 0) {
+			/* Analog Zero IF Mode */
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 44);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 173670);
+		}
+		if (state->Mode == 1) /* Digital Mode */ {
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 245760);
+		}
+	}
+
+	if (VCO_Range == 4) {
+		status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
+		status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+		status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
+		status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+		status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
+		status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+		status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+		status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
+		if (state->Mode == 0 && state->IF_Mode == 1) {
+			/* Analog Low IF Mode */
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 206438);
+		}
+		if (state->Mode == 0 && state->IF_Mode == 0) {
+			/* Analog Zero IF Mode */
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 206438);
+		}
+		if (state->Mode == 1) /* Digital Mode */ {
+			status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+			status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+			status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
+			status += MXL_ControlWrite(fe,
+				CHCAL_FRAC_MOD_RF, 212992);
+		}
+	}
+
+	return status;
+}
+
+static u16 MXL_Hystersis_Test(struct dvb_frontend *fe, int Hystersis)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u16 status = 0;
+
+	if (Hystersis == 1)
+		status += MXL_ControlWrite(fe, DN_BYPASS_AGC_I2C, 1);
+
+	return status;
+}
+#endif
+/* End: Reference driver code found in the Realtek driver that
+ * is copyright MaxLinear */
+
+/* ----------------------------------------------------------------
+ * Begin: Everything after here is new code to adapt the
+ * proprietary Realtek driver into a Linux API tuner.
+ * Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+ */
+static int mxl5005s_reset(struct dvb_frontend *fe)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	int ret = 0;
+
+	u8 buf[2] = { 0xff, 0x00 };
+	struct i2c_msg msg = { .addr = state->config->i2c_address, .flags = 0,
+			       .buf = buf, .len = 2 };
+
+	dprintk(2, "%s()\n", __func__);
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+		printk(KERN_WARNING "mxl5005s I2C reset failed\n");
+		ret = -EREMOTEIO;
+	}
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	return ret;
+}
+
+/* Write a single byte to a single reg, latch the value if required by
+ * following the transaction with the latch byte.
+ */
+static int mxl5005s_writereg(struct dvb_frontend *fe, u8 reg, u8 val, int latch)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u8 buf[3] = { reg, val, MXL5005S_LATCH_BYTE };
+	struct i2c_msg msg = { .addr = state->config->i2c_address, .flags = 0,
+			       .buf = buf, .len = 3 };
+
+	if (latch == 0)
+		msg.len = 2;
+
+	dprintk(2, "%s(0x%x, 0x%x, 0x%x)\n", __func__, reg, val, msg.addr);
+
+	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+		printk(KERN_WARNING "mxl5005s I2C write failed\n");
+		return -EREMOTEIO;
+	}
+	return 0;
+}
+
+static int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable,
+	u8 *datatable, u8 len)
+{
+	int ret = 0, i;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
+	for (i = 0 ; i < len-1; i++) {
+		ret = mxl5005s_writereg(fe, addrtable[i], datatable[i], 0);
+		if (ret < 0)
+			break;
+	}
+
+	ret = mxl5005s_writereg(fe, addrtable[i], datatable[i], 1);
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	return ret;
+}
+
+static int mxl5005s_init(struct dvb_frontend *fe)
+{
+	dprintk(1, "%s()\n", __func__);
+	return mxl5005s_reconfigure(fe, MXL_QAM, MXL5005S_BANDWIDTH_6MHZ);
+}
+
+static int mxl5005s_reconfigure(struct dvb_frontend *fe, u32 mod_type,
+	u32 bandwidth)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+
+	u8 AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
+	u8 ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
+	int TableLen;
+
+	dprintk(1, "%s(type=%d, bw=%d)\n", __func__, mod_type, bandwidth);
+
+	mxl5005s_reset(fe);
+
+	/* Tuner initialization stage 0 */
+	MXL_GetMasterControl(ByteTable, MC_SYNTH_RESET);
+	AddrTable[0] = MASTER_CONTROL_ADDR;
+	ByteTable[0] |= state->config->AgcMasterByte;
+
+	mxl5005s_writeregs(fe, AddrTable, ByteTable, 1);
+
+	mxl5005s_AssignTunerMode(fe, mod_type, bandwidth);
+
+	/* Tuner initialization stage 1 */
+	MXL_GetInitRegister(fe, AddrTable, ByteTable, &TableLen);
+
+	mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen);
+
+	return 0;
+}
+
+static int mxl5005s_AssignTunerMode(struct dvb_frontend *fe, u32 mod_type,
+	u32 bandwidth)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	struct mxl5005s_config *c = state->config;
+
+	InitTunerControls(fe);
+
+	/* Set MxL5005S parameters. */
+	MXL5005_TunerConfig(
+		fe,
+		c->mod_mode,
+		c->if_mode,
+		bandwidth,
+		c->if_freq,
+		c->xtal_freq,
+		c->agc_mode,
+		c->top,
+		c->output_load,
+		c->clock_out,
+		c->div_out,
+		c->cap_select,
+		c->rssi_enable,
+		mod_type,
+		c->tracking_filter);
+
+	return 0;
+}
+
+static int mxl5005s_set_params(struct dvb_frontend *fe,
+			       struct dvb_frontend_parameters *params)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	u32 req_mode, req_bw = 0;
+	int ret;
+
+	dprintk(1, "%s()\n", __func__);
+
+	if (fe->ops.info.type == FE_ATSC) {
+		switch (params->u.vsb.modulation) {
+		case VSB_8:
+			req_mode = MXL_ATSC; break;
+		default:
+		case QAM_64:
+		case QAM_256:
+		case QAM_AUTO:
+			req_mode = MXL_QAM; break;
+		}
+	} else
+		req_mode = MXL_DVBT;
+
+	/* Change tuner for new modulation type if reqd */
+	if (req_mode != state->current_mode) {
+		switch (req_mode) {
+		case VSB_8:
+		case QAM_64:
+		case QAM_256:
+		case QAM_AUTO:
+			req_bw  = MXL5005S_BANDWIDTH_6MHZ;
+			break;
+		default:
+			/* Assume DVB-T */
+			switch (params->u.ofdm.bandwidth) {
+			case BANDWIDTH_6_MHZ:
+				req_bw  = MXL5005S_BANDWIDTH_6MHZ;
+				break;
+			case BANDWIDTH_7_MHZ:
+				req_bw  = MXL5005S_BANDWIDTH_7MHZ;
+				break;
+			case BANDWIDTH_AUTO:
+			case BANDWIDTH_8_MHZ:
+				req_bw  = MXL5005S_BANDWIDTH_8MHZ;
+				break;
+			}
+		}
+
+		state->current_mode = req_mode;
+		ret = mxl5005s_reconfigure(fe, req_mode, req_bw);
+
+	} else
+		ret = 0;
+
+	if (ret == 0) {
+		dprintk(1, "%s() freq=%d\n", __func__, params->frequency);
+		ret = mxl5005s_SetRfFreqHz(fe, params->frequency);
+	}
+
+	return ret;
+}
+
+static int mxl5005s_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	dprintk(1, "%s()\n", __func__);
+
+	*frequency = state->RF_IN;
+
+	return 0;
+}
+
+static int mxl5005s_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+	struct mxl5005s_state *state = fe->tuner_priv;
+	dprintk(1, "%s()\n", __func__);
+
+	*bandwidth = state->Chan_Bandwidth;
+
+	return 0;
+}
+
+static int mxl5005s_release(struct dvb_frontend *fe)
+{
+	dprintk(1, "%s()\n", __func__);
+	kfree(fe->tuner_priv);
+	fe->tuner_priv = NULL;
+	return 0;
+}
+
+static const struct dvb_tuner_ops mxl5005s_tuner_ops = {
+	.info = {
+		.name           = "MaxLinear MXL5005S",
+		.frequency_min  =  48000000,
+		.frequency_max  = 860000000,
+		.frequency_step =     50000,
+	},
+
+	.release       = mxl5005s_release,
+	.init          = mxl5005s_init,
+
+	.set_params    = mxl5005s_set_params,
+	.get_frequency = mxl5005s_get_frequency,
+	.get_bandwidth = mxl5005s_get_bandwidth,
+};
+
+struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
+				     struct i2c_adapter *i2c,
+				     struct mxl5005s_config *config)
+{
+	struct mxl5005s_state *state = NULL;
+	dprintk(1, "%s()\n", __func__);
+
+	state = kzalloc(sizeof(struct mxl5005s_state), GFP_KERNEL);
+	if (state == NULL)
+		return NULL;
+
+	state->frontend = fe;
+	state->config = config;
+	state->i2c = i2c;
+	state->current_mode = MXL_QAM;
+
+	printk(KERN_INFO "MXL5005S: Attached at address 0x%02x\n",
+		config->i2c_address);
+
+	memcpy(&fe->ops.tuner_ops, &mxl5005s_tuner_ops,
+		sizeof(struct dvb_tuner_ops));
+
+	fe->tuner_priv = state;
+	return fe;
+}
+EXPORT_SYMBOL(mxl5005s_attach);
+
+MODULE_DESCRIPTION("MaxLinear MXL5005S silicon tuner driver");
+MODULE_AUTHOR("Steven Toth");
+MODULE_LICENSE("GPL");

+ 131 - 0
drivers/media/common/tuners/mxl5005s.h

@@ -0,0 +1,131 @@
+/*
+    MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
+
+    Copyright (C) 2008 MaxLinear
+    Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __MXL5005S_H
+#define __MXL5005S_H
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+struct mxl5005s_config {
+
+	/* 7 bit i2c address */
+	u8 i2c_address;
+
+#define IF_FREQ_4570000HZ    4570000
+#define IF_FREQ_4571429HZ    4571429
+#define IF_FREQ_5380000HZ    5380000
+#define IF_FREQ_36000000HZ  36000000
+#define IF_FREQ_36125000HZ  36125000
+#define IF_FREQ_36166667HZ  36166667
+#define IF_FREQ_44000000HZ  44000000
+	u32 if_freq;
+
+#define CRYSTAL_FREQ_4000000HZ    4000000
+#define CRYSTAL_FREQ_16000000HZ  16000000
+#define CRYSTAL_FREQ_25000000HZ  25000000
+#define CRYSTAL_FREQ_28800000HZ  28800000
+	u32 xtal_freq;
+
+#define MXL_DUAL_AGC   0
+#define MXL_SINGLE_AGC 1
+	u8 agc_mode;
+
+#define MXL_TF_DEFAULT	0
+#define MXL_TF_OFF	1
+#define MXL_TF_C	2
+#define MXL_TF_C_H	3
+#define MXL_TF_D	4
+#define MXL_TF_D_L	5
+#define MXL_TF_E	6
+#define MXL_TF_F	7
+#define MXL_TF_E_2	8
+#define MXL_TF_E_NA	9
+#define MXL_TF_G	10
+	u8 tracking_filter;
+
+#define MXL_RSSI_DISABLE	0
+#define MXL_RSSI_ENABLE		1
+	u8 rssi_enable;
+
+#define MXL_CAP_SEL_DISABLE	0
+#define MXL_CAP_SEL_ENABLE	1
+	u8 cap_select;
+
+#define MXL_DIV_OUT_1	0
+#define MXL_DIV_OUT_4	1
+	u8 div_out;
+
+#define MXL_CLOCK_OUT_DISABLE	0
+#define MXL_CLOCK_OUT_ENABLE	1
+	u8 clock_out;
+
+#define MXL5005S_IF_OUTPUT_LOAD_200_OHM 200
+#define MXL5005S_IF_OUTPUT_LOAD_300_OHM 300
+	u32 output_load;
+
+#define MXL5005S_TOP_5P5   55
+#define MXL5005S_TOP_7P2   72
+#define MXL5005S_TOP_9P2   92
+#define MXL5005S_TOP_11P0 110
+#define MXL5005S_TOP_12P9 129
+#define MXL5005S_TOP_14P7 147
+#define MXL5005S_TOP_16P8 168
+#define MXL5005S_TOP_19P4 194
+#define MXL5005S_TOP_21P2 212
+#define MXL5005S_TOP_23P2 232
+#define MXL5005S_TOP_25P2 252
+#define MXL5005S_TOP_27P1 271
+#define MXL5005S_TOP_29P2 292
+#define MXL5005S_TOP_31P7 317
+#define MXL5005S_TOP_34P9 349
+	u32 top;
+
+#define MXL_ANALOG_MODE  0
+#define MXL_DIGITAL_MODE 1
+	u8 mod_mode;
+
+#define MXL_ZERO_IF 0
+#define MXL_LOW_IF  1
+	u8 if_mode;
+
+	/* Stuff I don't know what to do with */
+	u8 AgcMasterByte;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_MXL5005S) || \
+	(defined(CONFIG_MEDIA_TUNER_MXL5005S_MODULE) && defined(MODULE))
+extern struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
+					    struct i2c_adapter *i2c,
+					    struct mxl5005s_config *config);
+#else
+static inline struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
+					    struct i2c_adapter *i2c,
+					    struct mxl5005s_config *config)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif /* CONFIG_DVB_TUNER_MXL5005S */
+
+#endif /* __MXL5005S_H */
+

+ 11 - 13
drivers/media/common/tuners/tda18271-common.c

@@ -227,9 +227,8 @@ int tda18271_charge_pump_source(struct dvb_frontend *fe,
 
 
 	regs[r_cp] &= ~0x20;
 	regs[r_cp] &= ~0x20;
 	regs[r_cp] |= ((force & 1) << 5);
 	regs[r_cp] |= ((force & 1) << 5);
-	tda18271_write_regs(fe, r_cp, 1);
 
 
-	return 0;
+	return tda18271_write_regs(fe, r_cp, 1);
 }
 }
 
 
 int tda18271_init_regs(struct dvb_frontend *fe)
 int tda18271_init_regs(struct dvb_frontend *fe)
@@ -487,16 +486,15 @@ int tda18271_set_standby_mode(struct dvb_frontend *fe,
 	struct tda18271_priv *priv = fe->tuner_priv;
 	struct tda18271_priv *priv = fe->tuner_priv;
 	unsigned char *regs = priv->tda18271_regs;
 	unsigned char *regs = priv->tda18271_regs;
 
 
-	tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt);
+	if (tda18271_debug & DBG_ADV)
+		tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt);
 
 
 	regs[R_EP3]  &= ~0xe0; /* clear sm, sm_lt, sm_xt */
 	regs[R_EP3]  &= ~0xe0; /* clear sm, sm_lt, sm_xt */
 	regs[R_EP3]  |= sm    ? (1 << 7) : 0 |
 	regs[R_EP3]  |= sm    ? (1 << 7) : 0 |
 			sm_lt ? (1 << 6) : 0 |
 			sm_lt ? (1 << 6) : 0 |
 			sm_xt ? (1 << 5) : 0;
 			sm_xt ? (1 << 5) : 0;
 
 
-	tda18271_write_regs(fe, R_EP3, 1);
-
-	return 0;
+	return tda18271_write_regs(fe, R_EP3, 1);
 }
 }
 
 
 /*---------------------------------------------------------------------*/
 /*---------------------------------------------------------------------*/
@@ -510,7 +508,7 @@ int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq)
 	u32 div;
 	u32 div;
 
 
 	int ret = tda18271_lookup_pll_map(fe, MAIN_PLL, &freq, &pd, &d);
 	int ret = tda18271_lookup_pll_map(fe, MAIN_PLL, &freq, &pd, &d);
-	if (ret < 0)
+	if (tda_fail(ret))
 		goto fail;
 		goto fail;
 
 
 	regs[R_MPD]   = (0x77 & pd);
 	regs[R_MPD]   = (0x77 & pd);
@@ -542,7 +540,7 @@ int tda18271_calc_cal_pll(struct dvb_frontend *fe, u32 freq)
 	u32 div;
 	u32 div;
 
 
 	int ret = tda18271_lookup_pll_map(fe, CAL_PLL, &freq, &pd, &d);
 	int ret = tda18271_lookup_pll_map(fe, CAL_PLL, &freq, &pd, &d);
-	if (ret < 0)
+	if (tda_fail(ret))
 		goto fail;
 		goto fail;
 
 
 	regs[R_CPD]   = pd;
 	regs[R_CPD]   = pd;
@@ -566,7 +564,7 @@ int tda18271_calc_bp_filter(struct dvb_frontend *fe, u32 *freq)
 	u8 val;
 	u8 val;
 
 
 	int ret = tda18271_lookup_map(fe, BP_FILTER, freq, &val);
 	int ret = tda18271_lookup_map(fe, BP_FILTER, freq, &val);
-	if (ret < 0)
+	if (tda_fail(ret))
 		goto fail;
 		goto fail;
 
 
 	regs[R_EP1]  &= ~0x07; /* clear bp filter bits */
 	regs[R_EP1]  &= ~0x07; /* clear bp filter bits */
@@ -583,7 +581,7 @@ int tda18271_calc_km(struct dvb_frontend *fe, u32 *freq)
 	u8 val;
 	u8 val;
 
 
 	int ret = tda18271_lookup_map(fe, RF_CAL_KMCO, freq, &val);
 	int ret = tda18271_lookup_map(fe, RF_CAL_KMCO, freq, &val);
-	if (ret < 0)
+	if (tda_fail(ret))
 		goto fail;
 		goto fail;
 
 
 	regs[R_EB13] &= ~0x7c; /* clear k & m bits */
 	regs[R_EB13] &= ~0x7c; /* clear k & m bits */
@@ -600,7 +598,7 @@ int tda18271_calc_rf_band(struct dvb_frontend *fe, u32 *freq)
 	u8 val;
 	u8 val;
 
 
 	int ret = tda18271_lookup_map(fe, RF_BAND, freq, &val);
 	int ret = tda18271_lookup_map(fe, RF_BAND, freq, &val);
-	if (ret < 0)
+	if (tda_fail(ret))
 		goto fail;
 		goto fail;
 
 
 	regs[R_EP2]  &= ~0xe0; /* clear rf band bits */
 	regs[R_EP2]  &= ~0xe0; /* clear rf band bits */
@@ -617,7 +615,7 @@ int tda18271_calc_gain_taper(struct dvb_frontend *fe, u32 *freq)
 	u8 val;
 	u8 val;
 
 
 	int ret = tda18271_lookup_map(fe, GAIN_TAPER, freq, &val);
 	int ret = tda18271_lookup_map(fe, GAIN_TAPER, freq, &val);
-	if (ret < 0)
+	if (tda_fail(ret))
 		goto fail;
 		goto fail;
 
 
 	regs[R_EP2]  &= ~0x1f; /* clear gain taper bits */
 	regs[R_EP2]  &= ~0x1f; /* clear gain taper bits */
@@ -634,7 +632,7 @@ int tda18271_calc_ir_measure(struct dvb_frontend *fe, u32 *freq)
 	u8 val;
 	u8 val;
 
 
 	int ret = tda18271_lookup_map(fe, IR_MEASURE, freq, &val);
 	int ret = tda18271_lookup_map(fe, IR_MEASURE, freq, &val);
-	if (ret < 0)
+	if (tda_fail(ret))
 		goto fail;
 		goto fail;
 
 
 	regs[R_EP5] &= ~0x07;
 	regs[R_EP5] &= ~0x07;

+ 113 - 55
drivers/media/common/tuners/tda18271-fe.c

@@ -51,6 +51,7 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
 {
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 	struct tda18271_priv *priv = fe->tuner_priv;
 	unsigned char *regs = priv->tda18271_regs;
 	unsigned char *regs = priv->tda18271_regs;
+	int ret;
 	u32 N;
 	u32 N;
 
 
 	/* update TV broadcast parameters */
 	/* update TV broadcast parameters */
@@ -85,7 +86,9 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
 	/* update rf top / if top */
 	/* update rf top / if top */
 	regs[R_EB22]  = 0x00;
 	regs[R_EB22]  = 0x00;
 	regs[R_EB22] |= map->rfagc_top;
 	regs[R_EB22] |= map->rfagc_top;
-	tda18271_write_regs(fe, R_EB22, 1);
+	ret = tda18271_write_regs(fe, R_EB22, 1);
+	if (tda_fail(ret))
+		goto fail;
 
 
 	/* --------------------------------------------------------------- */
 	/* --------------------------------------------------------------- */
 
 
@@ -121,7 +124,9 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
 	/* agc1 has priority on agc2 */
 	/* agc1 has priority on agc2 */
 	regs[R_EB1]  &= ~0x01;
 	regs[R_EB1]  &= ~0x01;
 
 
-	tda18271_write_regs(fe, R_EB1, 1);
+	ret = tda18271_write_regs(fe, R_EB1, 1);
+	if (tda_fail(ret))
+		goto fail;
 
 
 	/* --------------------------------------------------------------- */
 	/* --------------------------------------------------------------- */
 
 
@@ -141,7 +146,9 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
 		break;
 		break;
 	}
 	}
 
 
-	tda18271_write_regs(fe, R_TM, 7);
+	ret = tda18271_write_regs(fe, R_TM, 7);
+	if (tda_fail(ret))
+		goto fail;
 
 
 	/* force charge pump source */
 	/* force charge pump source */
 	charge_pump_source(fe, 1);
 	charge_pump_source(fe, 1);
@@ -158,9 +165,9 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
 		regs[R_EP3] &= ~0x04;
 		regs[R_EP3] &= ~0x04;
 	else
 	else
 		regs[R_EP3] |= 0x04;
 		regs[R_EP3] |= 0x04;
-	tda18271_write_regs(fe, R_EP3, 1);
-
-	return 0;
+	ret = tda18271_write_regs(fe, R_EP3, 1);
+fail:
+	return ret;
 }
 }
 
 
 static int tda18271_read_thermometer(struct dvb_frontend *fe)
 static int tda18271_read_thermometer(struct dvb_frontend *fe)
@@ -213,11 +220,13 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
 	struct tda18271_priv *priv = fe->tuner_priv;
 	struct tda18271_priv *priv = fe->tuner_priv;
 	struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
 	struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
 	unsigned char *regs = priv->tda18271_regs;
 	unsigned char *regs = priv->tda18271_regs;
-	int tm_current, rfcal_comp, approx, i;
+	int tm_current, rfcal_comp, approx, i, ret;
 	u8 dc_over_dt, rf_tab;
 	u8 dc_over_dt, rf_tab;
 
 
 	/* power up */
 	/* power up */
-	tda18271_set_standby_mode(fe, 0, 0, 0);
+	ret = tda18271_set_standby_mode(fe, 0, 0, 0);
+	if (tda_fail(ret))
+		goto fail;
 
 
 	/* read die current temperature */
 	/* read die current temperature */
 	tm_current = tda18271_read_thermometer(fe);
 	tm_current = tda18271_read_thermometer(fe);
@@ -228,8 +237,8 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
 	rf_tab = regs[R_EB14];
 	rf_tab = regs[R_EB14];
 
 
 	i = tda18271_lookup_rf_band(fe, &freq, NULL);
 	i = tda18271_lookup_rf_band(fe, &freq, NULL);
-	if (i < 0)
-		return -EINVAL;
+	if (tda_fail(i))
+		return i;
 
 
 	if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) {
 	if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) {
 		approx = map[i].rf_a1 *
 		approx = map[i].rf_a1 *
@@ -250,35 +259,42 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
 	rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal);
 	rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal);
 
 
 	regs[R_EB14] = approx + rfcal_comp;
 	regs[R_EB14] = approx + rfcal_comp;
-	tda18271_write_regs(fe, R_EB14, 1);
-
-	return 0;
+	ret = tda18271_write_regs(fe, R_EB14, 1);
+fail:
+	return ret;
 }
 }
 
 
 static int tda18271_por(struct dvb_frontend *fe)
 static int tda18271_por(struct dvb_frontend *fe)
 {
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 	struct tda18271_priv *priv = fe->tuner_priv;
 	unsigned char *regs = priv->tda18271_regs;
 	unsigned char *regs = priv->tda18271_regs;
+	int ret;
 
 
 	/* power up detector 1 */
 	/* power up detector 1 */
 	regs[R_EB12] &= ~0x20;
 	regs[R_EB12] &= ~0x20;
-	tda18271_write_regs(fe, R_EB12, 1);
+	ret = tda18271_write_regs(fe, R_EB12, 1);
+	if (tda_fail(ret))
+		goto fail;
 
 
 	regs[R_EB18] &= ~0x80; /* turn agc1 loop on */
 	regs[R_EB18] &= ~0x80; /* turn agc1 loop on */
 	regs[R_EB18] &= ~0x03; /* set agc1_gain to  6 dB */
 	regs[R_EB18] &= ~0x03; /* set agc1_gain to  6 dB */
-	tda18271_write_regs(fe, R_EB18, 1);
+	ret = tda18271_write_regs(fe, R_EB18, 1);
+	if (tda_fail(ret))
+		goto fail;
 
 
 	regs[R_EB21] |= 0x03; /* set agc2_gain to -6 dB */
 	regs[R_EB21] |= 0x03; /* set agc2_gain to -6 dB */
 
 
 	/* POR mode */
 	/* POR mode */
-	tda18271_set_standby_mode(fe, 1, 0, 0);
+	ret = tda18271_set_standby_mode(fe, 1, 0, 0);
+	if (tda_fail(ret))
+		goto fail;
 
 
 	/* disable 1.5 MHz low pass filter */
 	/* disable 1.5 MHz low pass filter */
 	regs[R_EB23] &= ~0x04; /* forcelp_fc2_en = 0 */
 	regs[R_EB23] &= ~0x04; /* forcelp_fc2_en = 0 */
 	regs[R_EB23] &= ~0x02; /* XXX: lp_fc[2] = 0 */
 	regs[R_EB23] &= ~0x02; /* XXX: lp_fc[2] = 0 */
-	tda18271_write_regs(fe, R_EB21, 3);
-
-	return 0;
+	ret = tda18271_write_regs(fe, R_EB21, 3);
+fail:
+	return ret;
 }
 }
 
 
 static int tda18271_calibrate_rf(struct dvb_frontend *fe, u32 freq)
 static int tda18271_calibrate_rf(struct dvb_frontend *fe, u32 freq)
@@ -389,7 +405,7 @@ static int tda18271_powerscan(struct dvb_frontend *fe,
 {
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 	struct tda18271_priv *priv = fe->tuner_priv;
 	unsigned char *regs = priv->tda18271_regs;
 	unsigned char *regs = priv->tda18271_regs;
-	int sgn, bcal, count, wait;
+	int sgn, bcal, count, wait, ret;
 	u8 cid_target;
 	u8 cid_target;
 	u16 count_limit;
 	u16 count_limit;
 	u32 freq;
 	u32 freq;
@@ -421,7 +437,9 @@ static int tda18271_powerscan(struct dvb_frontend *fe,
 	tda18271_write_regs(fe, R_EP2, 1);
 	tda18271_write_regs(fe, R_EP2, 1);
 
 
 	/* read power detection info, stored in EB10 */
 	/* read power detection info, stored in EB10 */
-	tda18271_read_extended(fe);
+	ret = tda18271_read_extended(fe);
+	if (tda_fail(ret))
+		return ret;
 
 
 	/* algorithm initialization */
 	/* algorithm initialization */
 	sgn = 1;
 	sgn = 1;
@@ -447,7 +465,9 @@ static int tda18271_powerscan(struct dvb_frontend *fe,
 		tda18271_write_regs(fe, R_EP2, 1);
 		tda18271_write_regs(fe, R_EP2, 1);
 
 
 		/* read power detection info, stored in EB10 */
 		/* read power detection info, stored in EB10 */
-		tda18271_read_extended(fe);
+		ret = tda18271_read_extended(fe);
+		if (tda_fail(ret))
+			return ret;
 
 
 		count += 200;
 		count += 200;
 
 
@@ -478,6 +498,7 @@ static int tda18271_powerscan_init(struct dvb_frontend *fe)
 {
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 	struct tda18271_priv *priv = fe->tuner_priv;
 	unsigned char *regs = priv->tda18271_regs;
 	unsigned char *regs = priv->tda18271_regs;
+	int ret;
 
 
 	/* set standard to digital */
 	/* set standard to digital */
 	regs[R_EP3]  &= ~0x1f; /* clear std bits */
 	regs[R_EP3]  &= ~0x1f; /* clear std bits */
@@ -489,10 +510,14 @@ static int tda18271_powerscan_init(struct dvb_frontend *fe)
 	/* update IF output level & IF notch frequency */
 	/* update IF output level & IF notch frequency */
 	regs[R_EP4]  &= ~0x1c; /* clear if level bits */
 	regs[R_EP4]  &= ~0x1c; /* clear if level bits */
 
 
-	tda18271_write_regs(fe, R_EP3, 2);
+	ret = tda18271_write_regs(fe, R_EP3, 2);
+	if (tda_fail(ret))
+		goto fail;
 
 
 	regs[R_EB18] &= ~0x03; /* set agc1_gain to   6 dB */
 	regs[R_EB18] &= ~0x03; /* set agc1_gain to   6 dB */
-	tda18271_write_regs(fe, R_EB18, 1);
+	ret = tda18271_write_regs(fe, R_EB18, 1);
+	if (tda_fail(ret))
+		goto fail;
 
 
 	regs[R_EB21] &= ~0x03; /* set agc2_gain to -15 dB */
 	regs[R_EB21] &= ~0x03; /* set agc2_gain to -15 dB */
 
 
@@ -500,9 +525,9 @@ static int tda18271_powerscan_init(struct dvb_frontend *fe)
 	regs[R_EB23] |= 0x04; /* forcelp_fc2_en = 1 */
 	regs[R_EB23] |= 0x04; /* forcelp_fc2_en = 1 */
 	regs[R_EB23] |= 0x02; /* lp_fc[2] = 1 */
 	regs[R_EB23] |= 0x02; /* lp_fc[2] = 1 */
 
 
-	tda18271_write_regs(fe, R_EB21, 3);
-
-	return 0;
+	ret = tda18271_write_regs(fe, R_EB21, 3);
+fail:
+	return ret;
 }
 }
 
 
 static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
 static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
@@ -521,7 +546,7 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
 
 
 	i = tda18271_lookup_rf_band(fe, &freq, NULL);
 	i = tda18271_lookup_rf_band(fe, &freq, NULL);
 
 
-	if (i < 0)
+	if (tda_fail(i))
 		return i;
 		return i;
 
 
 	rf_default[RF1] = 1000 * map[i].rf1_def;
 	rf_default[RF1] = 1000 * map[i].rf1_def;
@@ -535,6 +560,8 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
 
 
 		/* look for optimized calibration frequency */
 		/* look for optimized calibration frequency */
 		bcal = tda18271_powerscan(fe, &rf_default[rf], &rf_freq[rf]);
 		bcal = tda18271_powerscan(fe, &rf_default[rf], &rf_freq[rf]);
+		if (tda_fail(bcal))
+			return bcal;
 
 
 		tda18271_calc_rf_cal(fe, &rf_freq[rf]);
 		tda18271_calc_rf_cal(fe, &rf_freq[rf]);
 		prog_tab[rf] = regs[R_EB14];
 		prog_tab[rf] = regs[R_EB14];
@@ -575,22 +602,29 @@ static int tda18271_calc_rf_filter_curve(struct dvb_frontend *fe)
 {
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 	struct tda18271_priv *priv = fe->tuner_priv;
 	unsigned int i;
 	unsigned int i;
+	int ret;
 
 
 	tda_info("tda18271: performing RF tracking filter calibration\n");
 	tda_info("tda18271: performing RF tracking filter calibration\n");
 
 
 	/* wait for die temperature stabilization */
 	/* wait for die temperature stabilization */
 	msleep(200);
 	msleep(200);
 
 
-	tda18271_powerscan_init(fe);
+	ret = tda18271_powerscan_init(fe);
+	if (tda_fail(ret))
+		goto fail;
 
 
 	/* rf band calibration */
 	/* rf band calibration */
-	for (i = 0; priv->rf_cal_state[i].rfmax != 0; i++)
+	for (i = 0; priv->rf_cal_state[i].rfmax != 0; i++) {
+		ret =
 		tda18271_rf_tracking_filters_init(fe, 1000 *
 		tda18271_rf_tracking_filters_init(fe, 1000 *
 						  priv->rf_cal_state[i].rfmax);
 						  priv->rf_cal_state[i].rfmax);
+		if (tda_fail(ret))
+			goto fail;
+	}
 
 
 	priv->tm_rfcal = tda18271_read_thermometer(fe);
 	priv->tm_rfcal = tda18271_read_thermometer(fe);
-
-	return 0;
+fail:
+	return ret;
 }
 }
 
 
 /* ------------------------------------------------------------------ */
 /* ------------------------------------------------------------------ */
@@ -599,6 +633,7 @@ static int tda18271c2_rf_cal_init(struct dvb_frontend *fe)
 {
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 	struct tda18271_priv *priv = fe->tuner_priv;
 	unsigned char *regs = priv->tda18271_regs;
 	unsigned char *regs = priv->tda18271_regs;
+	int ret;
 
 
 	/* test RF_CAL_OK to see if we need init */
 	/* test RF_CAL_OK to see if we need init */
 	if ((regs[R_EP1] & 0x10) == 0)
 	if ((regs[R_EP1] & 0x10) == 0)
@@ -607,15 +642,22 @@ static int tda18271c2_rf_cal_init(struct dvb_frontend *fe)
 	if (priv->cal_initialized)
 	if (priv->cal_initialized)
 		return 0;
 		return 0;
 
 
-	tda18271_calc_rf_filter_curve(fe);
+	ret = tda18271_calc_rf_filter_curve(fe);
+	if (tda_fail(ret))
+		goto fail;
 
 
-	tda18271_por(fe);
+	ret = tda18271_por(fe);
+	if (tda_fail(ret))
+		goto fail;
 
 
 	tda_info("tda18271: RF tracking filter calibration complete\n");
 	tda_info("tda18271: RF tracking filter calibration complete\n");
 
 
 	priv->cal_initialized = true;
 	priv->cal_initialized = true;
-
-	return 0;
+	goto end;
+fail:
+	tda_info("tda18271: RF tracking filter calibration failed!\n");
+end:
+	return ret;
 }
 }
 
 
 static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe,
 static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe,
@@ -623,6 +665,7 @@ static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe,
 {
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 	struct tda18271_priv *priv = fe->tuner_priv;
 	unsigned char *regs = priv->tda18271_regs;
 	unsigned char *regs = priv->tda18271_regs;
+	int ret;
 	u32 N = 0;
 	u32 N = 0;
 
 
 	/* calculate bp filter */
 	/* calculate bp filter */
@@ -671,7 +714,10 @@ static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe,
 
 
 	tda18271_calc_main_pll(fe, N);
 	tda18271_calc_main_pll(fe, N);
 
 
-	tda18271_write_regs(fe, R_EP3, 11);
+	ret = tda18271_write_regs(fe, R_EP3, 11);
+	if (tda_fail(ret))
+		return ret;
+
 	msleep(5); /* RF tracking filter calibration initialization */
 	msleep(5); /* RF tracking filter calibration initialization */
 
 
 	/* search for K,M,CO for RF calibration */
 	/* search for K,M,CO for RF calibration */
@@ -719,45 +765,56 @@ static int tda18271_ir_cal_init(struct dvb_frontend *fe)
 {
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 	struct tda18271_priv *priv = fe->tuner_priv;
 	unsigned char *regs = priv->tda18271_regs;
 	unsigned char *regs = priv->tda18271_regs;
+	int ret;
 
 
-	tda18271_read_regs(fe);
+	ret = tda18271_read_regs(fe);
+	if (tda_fail(ret))
+		goto fail;
 
 
 	/* test IR_CAL_OK to see if we need init */
 	/* test IR_CAL_OK to see if we need init */
 	if ((regs[R_EP1] & 0x08) == 0)
 	if ((regs[R_EP1] & 0x08) == 0)
-		tda18271_init_regs(fe);
-
-	return 0;
+		ret = tda18271_init_regs(fe);
+fail:
+	return ret;
 }
 }
 
 
 static int tda18271_init(struct dvb_frontend *fe)
 static int tda18271_init(struct dvb_frontend *fe)
 {
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 	struct tda18271_priv *priv = fe->tuner_priv;
+	int ret;
 
 
 	mutex_lock(&priv->lock);
 	mutex_lock(&priv->lock);
 
 
 	/* power up */
 	/* power up */
-	tda18271_set_standby_mode(fe, 0, 0, 0);
+	ret = tda18271_set_standby_mode(fe, 0, 0, 0);
+	if (tda_fail(ret))
+		goto fail;
 
 
 	/* initialization */
 	/* initialization */
-	tda18271_ir_cal_init(fe);
+	ret = tda18271_ir_cal_init(fe);
+	if (tda_fail(ret))
+		goto fail;
 
 
 	if (priv->id == TDA18271HDC2)
 	if (priv->id == TDA18271HDC2)
 		tda18271c2_rf_cal_init(fe);
 		tda18271c2_rf_cal_init(fe);
-
+fail:
 	mutex_unlock(&priv->lock);
 	mutex_unlock(&priv->lock);
 
 
-	return 0;
+	return ret;
 }
 }
 
 
 static int tda18271_tune(struct dvb_frontend *fe,
 static int tda18271_tune(struct dvb_frontend *fe,
 			 struct tda18271_std_map_item *map, u32 freq, u32 bw)
 			 struct tda18271_std_map_item *map, u32 freq, u32 bw)
 {
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 	struct tda18271_priv *priv = fe->tuner_priv;
+	int ret;
 
 
 	tda_dbg("freq = %d, ifc = %d, bw = %d, agc_mode = %d, std = %d\n",
 	tda_dbg("freq = %d, ifc = %d, bw = %d, agc_mode = %d, std = %d\n",
 		freq, map->if_freq, bw, map->agc_mode, map->std);
 		freq, map->if_freq, bw, map->agc_mode, map->std);
 
 
-	tda18271_init(fe);
+	ret = tda18271_init(fe);
+	if (tda_fail(ret))
+		goto fail;
 
 
 	mutex_lock(&priv->lock);
 	mutex_lock(&priv->lock);
 
 
@@ -769,11 +826,11 @@ static int tda18271_tune(struct dvb_frontend *fe,
 		tda18271c2_rf_tracking_filters_correction(fe, freq);
 		tda18271c2_rf_tracking_filters_correction(fe, freq);
 		break;
 		break;
 	}
 	}
-	tda18271_channel_configuration(fe, map, freq, bw);
+	ret = tda18271_channel_configuration(fe, map, freq, bw);
 
 
 	mutex_unlock(&priv->lock);
 	mutex_unlock(&priv->lock);
-
-	return 0;
+fail:
+	return ret;
 }
 }
 
 
 /* ------------------------------------------------------------------ */
 /* ------------------------------------------------------------------ */
@@ -837,7 +894,7 @@ static int tda18271_set_params(struct dvb_frontend *fe,
 
 
 	ret = tda18271_tune(fe, map, freq, bw);
 	ret = tda18271_tune(fe, map, freq, bw);
 
 
-	if (ret < 0)
+	if (tda_fail(ret))
 		goto fail;
 		goto fail;
 
 
 	priv->frequency = freq;
 	priv->frequency = freq;
@@ -893,7 +950,7 @@ static int tda18271_set_analog_params(struct dvb_frontend *fe,
 
 
 	ret = tda18271_tune(fe, map, freq, 0);
 	ret = tda18271_tune(fe, map, freq, 0);
 
 
-	if (ret < 0)
+	if (tda_fail(ret))
 		goto fail;
 		goto fail;
 
 
 	priv->frequency = freq;
 	priv->frequency = freq;
@@ -905,16 +962,17 @@ fail:
 static int tda18271_sleep(struct dvb_frontend *fe)
 static int tda18271_sleep(struct dvb_frontend *fe)
 {
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
 	struct tda18271_priv *priv = fe->tuner_priv;
+	int ret;
 
 
 	mutex_lock(&priv->lock);
 	mutex_lock(&priv->lock);
 
 
 	/* standby mode w/ slave tuner output
 	/* standby mode w/ slave tuner output
 	 * & loop thru & xtal oscillator on */
 	 * & loop thru & xtal oscillator on */
-	tda18271_set_standby_mode(fe, 1, 0, 0);
+	ret = tda18271_set_standby_mode(fe, 1, 0, 0);
 
 
 	mutex_unlock(&priv->lock);
 	mutex_unlock(&priv->lock);
 
 
-	return 0;
+	return ret;
 }
 }
 
 
 static int tda18271_release(struct dvb_frontend *fe)
 static int tda18271_release(struct dvb_frontend *fe)
@@ -1095,10 +1153,10 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
 		if (cfg)
 		if (cfg)
 			priv->small_i2c = cfg->small_i2c;
 			priv->small_i2c = cfg->small_i2c;
 
 
-		if (tda18271_get_id(fe) < 0)
+		if (tda_fail(tda18271_get_id(fe)))
 			goto fail;
 			goto fail;
 
 
-		if (tda18271_assign_map_layout(fe) < 0)
+		if (tda_fail(tda18271_assign_map_layout(fe)))
 			goto fail;
 			goto fail;
 
 
 		mutex_lock(&priv->lock);
 		mutex_lock(&priv->lock);

+ 9 - 0
drivers/media/common/tuners/tda18271-priv.h

@@ -153,6 +153,15 @@ extern int tda18271_debug;
 #define tda_reg(fmt, arg...)  dprintk(KERN_DEBUG, DBG_REG,  fmt, ##arg)
 #define tda_reg(fmt, arg...)  dprintk(KERN_DEBUG, DBG_REG,  fmt, ##arg)
 #define tda_cal(fmt, arg...)  dprintk(KERN_DEBUG, DBG_CAL,  fmt, ##arg)
 #define tda_cal(fmt, arg...)  dprintk(KERN_DEBUG, DBG_CAL,  fmt, ##arg)
 
 
+#define tda_fail(ret)							     \
+({									     \
+	int __ret;							     \
+	__ret = (ret < 0);						     \
+	if (__ret)							     \
+		tda_printk(KERN_ERR, "error %d on line %d\n", ret, __LINE__);\
+	__ret;								     \
+})
+
 /*---------------------------------------------------------------------*/
 /*---------------------------------------------------------------------*/
 
 
 enum tda18271_map_type {
 enum tda18271_map_type {

+ 3 - 3
drivers/media/common/tuners/tea5767.c

@@ -373,14 +373,14 @@ int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr)
 
 
 	if ((rc = tuner_i2c_xfer_recv(&i2c, buffer, 7))< 5) {
 	if ((rc = tuner_i2c_xfer_recv(&i2c, buffer, 7))< 5) {
 		printk(KERN_WARNING "It is not a TEA5767. Received %i bytes.\n", rc);
 		printk(KERN_WARNING "It is not a TEA5767. Received %i bytes.\n", rc);
-		return EINVAL;
+		return -EINVAL;
 	}
 	}
 
 
 	/* If all bytes are the same then it's a TV tuner and not a tea5767 */
 	/* If all bytes are the same then it's a TV tuner and not a tea5767 */
 	if (buffer[0] == buffer[1] && buffer[0] == buffer[2] &&
 	if (buffer[0] == buffer[1] && buffer[0] == buffer[2] &&
 	    buffer[0] == buffer[3] && buffer[0] == buffer[4]) {
 	    buffer[0] == buffer[3] && buffer[0] == buffer[4]) {
 		printk(KERN_WARNING "All bytes are equal. It is not a TEA5767\n");
 		printk(KERN_WARNING "All bytes are equal. It is not a TEA5767\n");
-		return EINVAL;
+		return -EINVAL;
 	}
 	}
 
 
 	/*  Status bytes:
 	/*  Status bytes:
@@ -390,7 +390,7 @@ int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr)
 	 */
 	 */
 	if (((buffer[3] & 0x0f) != 0x00) || (buffer[4] != 0x00)) {
 	if (((buffer[3] & 0x0f) != 0x00) || (buffer[4] != 0x00)) {
 		printk(KERN_WARNING "Chip ID is not zero. It is not a TEA5767\n");
 		printk(KERN_WARNING "Chip ID is not zero. It is not a TEA5767\n");
-		return EINVAL;
+		return -EINVAL;
 	}
 	}
 
 
 
 

+ 5 - 4
drivers/media/common/tuners/xc5000.c

@@ -212,7 +212,7 @@ static void xc5000_TunerReset(struct dvb_frontend *fe)
 	dprintk(1, "%s()\n", __func__);
 	dprintk(1, "%s()\n", __func__);
 
 
 	if (priv->cfg->tuner_callback) {
 	if (priv->cfg->tuner_callback) {
-		ret = priv->cfg->tuner_callback(priv->cfg->priv,
+		ret = priv->cfg->tuner_callback(priv->devptr,
 						XC5000_TUNER_RESET, 0);
 						XC5000_TUNER_RESET, 0);
 		if (ret)
 		if (ret)
 			printk(KERN_ERR "xc5000: reset failed\n");
 			printk(KERN_ERR "xc5000: reset failed\n");
@@ -900,9 +900,9 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = {
 	.get_status	   = xc5000_get_status
 	.get_status	   = xc5000_get_status
 };
 };
 
 
-struct dvb_frontend * xc5000_attach(struct dvb_frontend *fe,
-	struct i2c_adapter *i2c,
-	struct xc5000_config *cfg)
+struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
+				   struct i2c_adapter *i2c,
+				   struct xc5000_config *cfg, void *devptr)
 {
 {
 	struct xc5000_priv *priv = NULL;
 	struct xc5000_priv *priv = NULL;
 	u16 id = 0;
 	u16 id = 0;
@@ -916,6 +916,7 @@ struct dvb_frontend * xc5000_attach(struct dvb_frontend *fe,
 	priv->cfg = cfg;
 	priv->cfg = cfg;
 	priv->bandwidth = BANDWIDTH_6_MHZ;
 	priv->bandwidth = BANDWIDTH_6_MHZ;
 	priv->i2c = i2c;
 	priv->i2c = i2c;
+	priv->devptr = devptr;
 
 
 	/* Check if firmware has been loaded. It is possible that another
 	/* Check if firmware has been loaded. It is possible that another
 	   instance of the driver has loaded the firmware.
 	   instance of the driver has loaded the firmware.

+ 12 - 10
drivers/media/common/tuners/xc5000.h

@@ -31,29 +31,31 @@ struct xc5000_config {
 	u8   i2c_address;
 	u8   i2c_address;
 	u32  if_khz;
 	u32  if_khz;
 
 
-	/* For each bridge framework, when it attaches either analog or digital,
-	 * it has to store a reference back to its _core equivalent structure,
-	 * so that it can service the hardware by steering gpio's etc.
-	 * Each bridge implementation is different so cast priv accordingly.
-	 * The xc5000 driver cares not for this value, other than ensuring
-	 * it's passed back to a bridge during tuner_callback().
-	 */
-	void *priv;
 	int  (*tuner_callback) (void *priv, int command, int arg);
 	int  (*tuner_callback) (void *priv, int command, int arg);
 };
 };
 
 
 /* xc5000 callback command */
 /* xc5000 callback command */
 #define XC5000_TUNER_RESET		0
 #define XC5000_TUNER_RESET		0
 
 
+/* For each bridge framework, when it attaches either analog or digital,
+ * it has to store a reference back to its _core equivalent structure,
+ * so that it can service the hardware by steering gpio's etc.
+ * Each bridge implementation is different so cast devptr accordingly.
+ * The xc5000 driver cares not for this value, other than ensuring
+ * it's passed back to a bridge during tuner_callback().
+ */
+
 #if defined(CONFIG_MEDIA_TUNER_XC5000) || \
 #if defined(CONFIG_MEDIA_TUNER_XC5000) || \
     (defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE))
     (defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE))
 extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
 extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
 					  struct i2c_adapter *i2c,
 					  struct i2c_adapter *i2c,
-					  struct xc5000_config *cfg);
+					  struct xc5000_config *cfg,
+					  void *devptr);
 #else
 #else
 static inline struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
 static inline struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
 						 struct i2c_adapter *i2c,
 						 struct i2c_adapter *i2c,
-						 struct xc5000_config *cfg)
+						 struct xc5000_config *cfg,
+						 void *devptr)
 {
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
 	return NULL;

+ 2 - 0
drivers/media/common/tuners/xc5000_priv.h

@@ -31,6 +31,8 @@ struct xc5000_priv {
 	u8  video_standard;
 	u8  video_standard;
 	u8  rf_mode;
 	u8  rf_mode;
 	u8  fwloaded;
 	u8  fwloaded;
+
+	void *devptr;
 };
 };
 
 
 #endif
 #endif

+ 1 - 1
drivers/media/dvb/b2c2/flexcop-fe-tuner.c

@@ -634,7 +634,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
 	}
 	}
 
 
 	/* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
 	/* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
-	fc->fe = dvb_attach(vp310_mt312_attach,
+	fc->fe = dvb_attach(mt312_attach,
 		&skystar23_samsung_tbdu18132_config, i2c);
 		&skystar23_samsung_tbdu18132_config, i2c);
 	if (fc->fe != NULL) {
 	if (fc->fe != NULL) {
 		ops = &fc->fe->ops;
 		ops = &fc->fe->ops;

+ 1 - 0
drivers/media/dvb/bt8xx/Kconfig

@@ -1,6 +1,7 @@
 config DVB_BT8XX
 config DVB_BT8XX
 	tristate "BT8xx based PCI cards"
 	tristate "BT8xx based PCI cards"
 	depends on DVB_CORE && PCI && I2C && VIDEO_BT848
 	depends on DVB_CORE && PCI && I2C && VIDEO_BT848
+	depends on HOTPLUG	# due to FW_LOADER
 	select DVB_MT352 if !DVB_FE_CUSTOMISE
 	select DVB_MT352 if !DVB_FE_CUSTOMISE
 	select DVB_SP887X if !DVB_FE_CUSTOMISE
 	select DVB_SP887X if !DVB_FE_CUSTOMISE
 	select DVB_NXT6000 if !DVB_FE_CUSTOMISE
 	select DVB_NXT6000 if !DVB_FE_CUSTOMISE

+ 1 - 1
drivers/media/dvb/cinergyT2/Kconfig

@@ -1,6 +1,6 @@
 config DVB_CINERGYT2
 config DVB_CINERGYT2
 	tristate "Terratec CinergyT2/qanu USB2 DVB-T receiver"
 	tristate "Terratec CinergyT2/qanu USB2 DVB-T receiver"
-	depends on DVB_CORE && USB
+	depends on DVB_CORE && USB && INPUT
 	help
 	help
 	  Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers
 	  Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers
 
 

+ 16 - 12
drivers/media/dvb/dvb-core/dvb_ca_en50221.c

@@ -910,15 +910,21 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
 	int curdelay = 100000000;
 	int curdelay = 100000000;
 	int slot;
 	int slot;
 
 
+	/* Beware of too high polling frequency, because one polling
+	 * call might take several hundred milliseconds until timeout!
+	 */
 	for (slot = 0; slot < ca->slot_count; slot++) {
 	for (slot = 0; slot < ca->slot_count; slot++) {
 		switch (ca->slot_info[slot].slot_state) {
 		switch (ca->slot_info[slot].slot_state) {
 		default:
 		default:
 		case DVB_CA_SLOTSTATE_NONE:
 		case DVB_CA_SLOTSTATE_NONE:
+			delay = HZ * 60;  /* 60s */
+			if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
+				delay = HZ * 5;  /* 5s */
+			break;
 		case DVB_CA_SLOTSTATE_INVALID:
 		case DVB_CA_SLOTSTATE_INVALID:
-			delay = HZ * 60;
-			if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) {
-				delay = HZ / 10;
-			}
+			delay = HZ * 60;  /* 60s */
+			if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
+				delay = HZ / 10;  /* 100ms */
 			break;
 			break;
 
 
 		case DVB_CA_SLOTSTATE_UNINITIALISED:
 		case DVB_CA_SLOTSTATE_UNINITIALISED:
@@ -926,19 +932,17 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
 		case DVB_CA_SLOTSTATE_VALIDATE:
 		case DVB_CA_SLOTSTATE_VALIDATE:
 		case DVB_CA_SLOTSTATE_WAITFR:
 		case DVB_CA_SLOTSTATE_WAITFR:
 		case DVB_CA_SLOTSTATE_LINKINIT:
 		case DVB_CA_SLOTSTATE_LINKINIT:
-			delay = HZ / 10;
+			delay = HZ / 10;  /* 100ms */
 			break;
 			break;
 
 
 		case DVB_CA_SLOTSTATE_RUNNING:
 		case DVB_CA_SLOTSTATE_RUNNING:
-			delay = HZ * 60;
-			if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) {
-				delay = HZ / 10;
-			}
+			delay = HZ * 60;  /* 60s */
+			if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
+				delay = HZ / 10;  /* 100ms */
 			if (ca->open) {
 			if (ca->open) {
 				if ((!ca->slot_info[slot].da_irq_supported) ||
 				if ((!ca->slot_info[slot].da_irq_supported) ||
-				    (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_DA))) {
-					delay = HZ / 10;
-				}
+				    (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_DA)))
+					delay = HZ / 10;  /* 100ms */
 			}
 			}
 			break;
 			break;
 		}
 		}

+ 1 - 0
drivers/media/dvb/dvb-usb/Kconfig

@@ -1,6 +1,7 @@
 config DVB_USB
 config DVB_USB
 	tristate "Support for various USB DVB devices"
 	tristate "Support for various USB DVB devices"
 	depends on DVB_CORE && USB && I2C
 	depends on DVB_CORE && USB && I2C
+	depends on HOTPLUG	# due to FW_LOADER
 	select FW_LOADER
 	select FW_LOADER
 	help
 	help
 	  By enabling this you will be able to choose the various supported
 	  By enabling this you will be able to choose the various supported

+ 9 - 9
drivers/media/dvb/frontends/Kconfig

@@ -30,7 +30,7 @@ config DVB_CX24123
 	  A DVB-S tuner module. Say Y when you want to support this frontend.
 	  A DVB-S tuner module. Say Y when you want to support this frontend.
 
 
 config DVB_MT312
 config DVB_MT312
-	tristate "Zarlink VP310/MT312 based"
+	tristate "Zarlink VP310/MT312/ZL10313 based"
 	depends on DVB_CORE && I2C
 	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
 	help
 	help
@@ -97,7 +97,7 @@ comment "DVB-T (terrestrial) frontends"
 
 
 config DVB_SP8870
 config DVB_SP8870
 	tristate "Spase sp8870 based"
 	tristate "Spase sp8870 based"
-	depends on DVB_CORE && I2C
+	depends on DVB_CORE && I2C && HOTPLUG
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
 	select FW_LOADER
 	select FW_LOADER
 	help
 	help
@@ -110,7 +110,7 @@ config DVB_SP8870
 
 
 config DVB_SP887X
 config DVB_SP887X
 	tristate "Spase sp887x based"
 	tristate "Spase sp887x based"
-	depends on DVB_CORE && I2C
+	depends on DVB_CORE && I2C && HOTPLUG
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
 	select FW_LOADER
 	select FW_LOADER
 	help
 	help
@@ -144,7 +144,7 @@ config DVB_L64781
 
 
 config DVB_TDA1004X
 config DVB_TDA1004X
 	tristate "Philips TDA10045H/TDA10046H based"
 	tristate "Philips TDA10045H/TDA10046H based"
-	depends on DVB_CORE && I2C
+	depends on DVB_CORE && I2C && HOTPLUG
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
 	select FW_LOADER
 	select FW_LOADER
 	help
 	help
@@ -211,7 +211,7 @@ config DVB_DIB7000P
 
 
 config DVB_TDA10048
 config DVB_TDA10048
 	tristate "Philips TDA10048HN based"
 	tristate "Philips TDA10048HN based"
-	depends on DVB_CORE && I2C
+	depends on DVB_CORE && I2C && HOTPLUG
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
 	select FW_LOADER
 	select FW_LOADER
 	help
 	help
@@ -253,7 +253,7 @@ comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends"
 
 
 config DVB_NXT200X
 config DVB_NXT200X
 	tristate "NxtWave Communications NXT2002/NXT2004 based"
 	tristate "NxtWave Communications NXT2002/NXT2004 based"
-	depends on DVB_CORE && I2C
+	depends on DVB_CORE && I2C && HOTPLUG
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
 	select FW_LOADER
 	select FW_LOADER
 	help
 	help
@@ -268,7 +268,7 @@ config DVB_NXT200X
 
 
 config DVB_OR51211
 config DVB_OR51211
 	tristate "Oren OR51211 based"
 	tristate "Oren OR51211 based"
-	depends on DVB_CORE && I2C
+	depends on DVB_CORE && I2C && HOTPLUG
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
 	select FW_LOADER
 	select FW_LOADER
 	help
 	help
@@ -281,7 +281,7 @@ config DVB_OR51211
 
 
 config DVB_OR51132
 config DVB_OR51132
 	tristate "Oren OR51132 based"
 	tristate "Oren OR51132 based"
-	depends on DVB_CORE && I2C
+	depends on DVB_CORE && I2C && HOTPLUG
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
 	select FW_LOADER
 	select FW_LOADER
 	help
 	help
@@ -297,7 +297,7 @@ config DVB_OR51132
 
 
 config DVB_BCM3510
 config DVB_BCM3510
 	tristate "Broadcom BCM3510"
 	tristate "Broadcom BCM3510"
-	depends on DVB_CORE && I2C
+	depends on DVB_CORE && I2C && HOTPLUG
 	default m if DVB_FE_CUSTOMISE
 	default m if DVB_FE_CUSTOMISE
 	select FW_LOADER
 	select FW_LOADER
 	help
 	help

+ 1 - 1
drivers/media/dvb/frontends/itd1000.c

@@ -195,7 +195,7 @@ static void itd1000_set_vco(struct itd1000_state *state, u32 freq_khz)
 	}
 	}
 }
 }
 
 
-struct {
+static const struct {
 	u32 freq;
 	u32 freq;
 	u8 values[10]; /* RFTR, RFST1 - RFST9 */
 	u8 values[10]; /* RFTR, RFST1 - RFST9 */
 } itd1000_fre_values[] = {
 } itd1000_fre_values[] = {

+ 5 - 4
drivers/media/dvb/frontends/mt312.c

@@ -737,7 +737,7 @@ static void mt312_release(struct dvb_frontend *fe)
 }
 }
 
 
 #define MT312_SYS_CLK		90000000UL	/* 90 MHz */
 #define MT312_SYS_CLK		90000000UL	/* 90 MHz */
-static struct dvb_frontend_ops vp310_mt312_ops = {
+static struct dvb_frontend_ops mt312_ops = {
 
 
 	.info = {
 	.info = {
 		.name = "Zarlink ???? DVB-S",
 		.name = "Zarlink ???? DVB-S",
@@ -776,7 +776,7 @@ static struct dvb_frontend_ops vp310_mt312_ops = {
 	.set_voltage = mt312_set_voltage,
 	.set_voltage = mt312_set_voltage,
 };
 };
 
 
-struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config,
+struct dvb_frontend *mt312_attach(const struct mt312_config *config,
 					struct i2c_adapter *i2c)
 					struct i2c_adapter *i2c)
 {
 {
 	struct mt312_state *state = NULL;
 	struct mt312_state *state = NULL;
@@ -795,7 +795,7 @@ struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config,
 		goto error;
 		goto error;
 
 
 	/* create dvb_frontend */
 	/* create dvb_frontend */
-	memcpy(&state->frontend.ops, &vp310_mt312_ops,
+	memcpy(&state->frontend.ops, &mt312_ops,
 		sizeof(struct dvb_frontend_ops));
 		sizeof(struct dvb_frontend_ops));
 	state->frontend.demodulator_priv = state;
 	state->frontend.demodulator_priv = state;
 
 
@@ -827,12 +827,13 @@ error:
 	kfree(state);
 	kfree(state);
 	return NULL;
 	return NULL;
 }
 }
-EXPORT_SYMBOL(vp310_mt312_attach);
+EXPORT_SYMBOL(mt312_attach);
 
 
 module_param(debug, int, 0644);
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
 
 
 MODULE_DESCRIPTION("Zarlink VP310/MT312/ZL10313 DVB-S Demodulator driver");
 MODULE_DESCRIPTION("Zarlink VP310/MT312/ZL10313 DVB-S Demodulator driver");
 MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
 MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
+MODULE_AUTHOR("Matthias Schwarzott <zzam@gentoo.org>");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 
 

+ 2 - 2
drivers/media/dvb/frontends/mt312.h

@@ -37,10 +37,10 @@ struct mt312_config {
 };
 };
 
 
 #if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE))
 #if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE))
-struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config,
+struct dvb_frontend *mt312_attach(const struct mt312_config *config,
 					struct i2c_adapter *i2c);
 					struct i2c_adapter *i2c);
 #else
 #else
-static inline struct dvb_frontend *vp310_mt312_attach(
+static inline struct dvb_frontend *mt312_attach(
 	const struct mt312_config *config, struct i2c_adapter *i2c)
 	const struct mt312_config *config, struct i2c_adapter *i2c)
 {
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);

+ 2 - 0
drivers/media/dvb/ttpci/Kconfig

@@ -5,6 +5,7 @@ config TTPCI_EEPROM
 config DVB_AV7110
 config DVB_AV7110
 	tristate "AV7110 cards"
 	tristate "AV7110 cards"
 	depends on DVB_CORE && PCI && I2C
 	depends on DVB_CORE && PCI && I2C
+	depends on HOTPLUG
 	select FW_LOADER if !DVB_AV7110_FIRMWARE
 	select FW_LOADER if !DVB_AV7110_FIRMWARE
 	select TTPCI_EEPROM
 	select TTPCI_EEPROM
 	select VIDEO_SAA7146_VV
 	select VIDEO_SAA7146_VV
@@ -123,6 +124,7 @@ config DVB_BUDGET_AV
 	depends on DVB_BUDGET_CORE && I2C
 	depends on DVB_BUDGET_CORE && I2C
 	select VIDEO_SAA7146_VV
 	select VIDEO_SAA7146_VV
 	depends on VIDEO_DEV	# dependencies of VIDEO_SAA7146_VV
 	depends on VIDEO_DEV	# dependencies of VIDEO_SAA7146_VV
+	depends on HOTPLUG	# dependency of FW_LOADER
 	select DVB_PLL if !DVB_FE_CUSTOMISE
 	select DVB_PLL if !DVB_FE_CUSTOMISE
 	select DVB_STV0299 if !DVB_FE_CUSTOMISE
 	select DVB_STV0299 if !DVB_FE_CUSTOMISE
 	select DVB_TDA1004X if !DVB_FE_CUSTOMISE
 	select DVB_TDA1004X if !DVB_FE_CUSTOMISE

+ 1 - 0
drivers/media/dvb/ttusb-dec/Kconfig

@@ -1,6 +1,7 @@
 config DVB_TTUSB_DEC
 config DVB_TTUSB_DEC
 	tristate "Technotrend/Hauppauge USB DEC devices"
 	tristate "Technotrend/Hauppauge USB DEC devices"
 	depends on DVB_CORE && USB
 	depends on DVB_CORE && USB
+	depends on HOTPLUG	# due to FW_LOADER
 	select FW_LOADER
 	select FW_LOADER
 	select CRC32
 	select CRC32
 	help
 	help

+ 7 - 3
drivers/media/video/Kconfig

@@ -44,6 +44,10 @@ config VIDEO_TVEEPROM
 	tristate
 	tristate
 	depends on I2C
 	depends on I2C
 
 
+config VIDEO_TUNER
+	tristate
+	depends on MEDIA_TUNER
+
 #
 #
 # Multimedia Video device configuration
 # Multimedia Video device configuration
 #
 #
@@ -690,7 +694,7 @@ config VIDEO_MXB
 	tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
 	tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
 	depends on PCI && VIDEO_V4L1 && I2C
 	depends on PCI && VIDEO_V4L1 && I2C
 	select VIDEO_SAA7146_VV
 	select VIDEO_SAA7146_VV
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO
@@ -906,7 +910,7 @@ config SOC_CAMERA
 
 
 config SOC_CAMERA_MT9M001
 config SOC_CAMERA_MT9M001
 	tristate "mt9m001 support"
 	tristate "mt9m001 support"
-	depends on SOC_CAMERA
+	depends on SOC_CAMERA && I2C
 	select GPIO_PCA953X if MT9M001_PCA9536_SWITCH
 	select GPIO_PCA953X if MT9M001_PCA9536_SWITCH
 	help
 	help
 	  This driver supports MT9M001 cameras from Micron, monochrome
 	  This driver supports MT9M001 cameras from Micron, monochrome
@@ -921,7 +925,7 @@ config MT9M001_PCA9536_SWITCH
 
 
 config SOC_CAMERA_MT9V022
 config SOC_CAMERA_MT9V022
 	tristate "mt9v022 support"
 	tristate "mt9v022 support"
-	depends on SOC_CAMERA
+	depends on SOC_CAMERA && I2C
 	select GPIO_PCA953X if MT9V022_PCA9536_SWITCH
 	select GPIO_PCA953X if MT9V022_PCA9536_SWITCH
 	help
 	help
 	  This driver supports MT9V022 cameras from Micron
 	  This driver supports MT9V022 cameras from Micron

+ 1 - 1
drivers/media/video/Makefile

@@ -84,7 +84,7 @@ obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o
 obj-$(CONFIG_VIDEO_DPC) += dpc7146.o
 obj-$(CONFIG_VIDEO_DPC) += dpc7146.o
 obj-$(CONFIG_TUNER_3036) += tuner-3036.o
 obj-$(CONFIG_TUNER_3036) += tuner-3036.o
 
 
-obj-$(CONFIG_MEDIA_TUNER) += tuner.o
+obj-$(CONFIG_VIDEO_TUNER) += tuner.o
 
 
 obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
 obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
 obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
 obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o

+ 2 - 1
drivers/media/video/au0828/Kconfig

@@ -1,8 +1,9 @@
 
 
 config VIDEO_AU0828
 config VIDEO_AU0828
 	tristate "Auvitek AU0828 support"
 	tristate "Auvitek AU0828 support"
-       depends on VIDEO_DEV && I2C && INPUT && DVB_CORE
+	depends on VIDEO_DEV && I2C && INPUT && DVB_CORE && USB
 	select I2C_ALGOBIT
 	select I2C_ALGOBIT
+	select VIDEO_TVEEPROM
 	select DVB_AU8522 if !DVB_FE_CUSTOMIZE
 	select DVB_AU8522 if !DVB_FE_CUSTOMIZE
 	select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
 	select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
 	---help---
 	---help---

+ 2 - 4
drivers/media/video/au0828/au0828-dvb.c

@@ -337,12 +337,10 @@ int au0828_dvb_register(struct au0828_dev *dev)
 		dvb->frontend = dvb_attach(au8522_attach,
 		dvb->frontend = dvb_attach(au8522_attach,
 				&hauppauge_hvr950q_config,
 				&hauppauge_hvr950q_config,
 				&dev->i2c_adap);
 				&dev->i2c_adap);
-		if (dvb->frontend != NULL) {
-			hauppauge_hvr950q_tunerconfig.priv = dev;
+		if (dvb->frontend != NULL)
 			dvb_attach(xc5000_attach, dvb->frontend,
 			dvb_attach(xc5000_attach, dvb->frontend,
 				&dev->i2c_adap,
 				&dev->i2c_adap,
-				&hauppauge_hvr950q_tunerconfig);
-		}
+				&hauppauge_hvr950q_tunerconfig, dev);
 		break;
 		break;
 	default:
 	default:
 		printk(KERN_WARNING "The frontend of your DVB/ATSC card "
 		printk(KERN_WARNING "The frontend of your DVB/ATSC card "

+ 2 - 1
drivers/media/video/bt8xx/Kconfig

@@ -1,12 +1,13 @@
 config VIDEO_BT848
 config VIDEO_BT848
 	tristate "BT848 Video For Linux"
 	tristate "BT848 Video For Linux"
 	depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 && INPUT
 	depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 && INPUT
+	depends on HOTPLUG	# due to FW_LOADER
 	select I2C_ALGOBIT
 	select I2C_ALGOBIT
 	select FW_LOADER
 	select FW_LOADER
 	select VIDEO_BTCX
 	select VIDEO_BTCX
 	select VIDEOBUF_DMA_SG
 	select VIDEOBUF_DMA_SG
 	select VIDEO_IR
 	select VIDEO_IR
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select VIDEO_TVEEPROM
 	select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO

+ 4 - 1
drivers/media/video/cx18/Kconfig

@@ -1,14 +1,17 @@
 config VIDEO_CX18
 config VIDEO_CX18
 	tristate "Conexant cx23418 MPEG encoder support"
 	tristate "Conexant cx23418 MPEG encoder support"
 	depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
 	depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
+	depends on INPUT	# due to VIDEO_IR
+	depends on HOTPLUG	# due to FW_LOADER
 	select I2C_ALGOBIT
 	select I2C_ALGOBIT
 	select FW_LOADER
 	select FW_LOADER
 	select VIDEO_IR
 	select VIDEO_IR
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select VIDEO_TVEEPROM
 	select VIDEO_CX2341X
 	select VIDEO_CX2341X
 	select VIDEO_CS5345
 	select VIDEO_CS5345
 	select DVB_S5H1409
 	select DVB_S5H1409
+	select MEDIA_TUNER_MXL5005S
 	---help---
 	---help---
 	  This is a video4linux driver for Conexant cx23418 based
 	  This is a video4linux driver for Conexant cx23418 based
 	  PCI combo video recorder devices.
 	  PCI combo video recorder devices.

+ 14 - 11
drivers/media/video/cx18/cx18-cards.c

@@ -47,11 +47,12 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = {
 static const struct cx18_card cx18_card_hvr1600_esmt = {
 static const struct cx18_card cx18_card_hvr1600_esmt = {
 	.type = CX18_CARD_HVR_1600_ESMT,
 	.type = CX18_CARD_HVR_1600_ESMT,
 	.name = "Hauppauge HVR-1600",
 	.name = "Hauppauge HVR-1600",
-	.comment = "DVB & VBI are not yet supported\n",
+	.comment = "VBI is not yet supported\n",
 	.v4l2_capabilities = CX18_CAP_ENCODER,
 	.v4l2_capabilities = CX18_CAP_ENCODER,
 	.hw_audio_ctrl = CX18_HW_CX23418,
 	.hw_audio_ctrl = CX18_HW_CX23418,
 	.hw_muxer = CX18_HW_CS5345,
 	.hw_muxer = CX18_HW_CS5345,
-	.hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345,
+	.hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
+		  CX18_HW_CS5345 | CX18_HW_DVB,
 	.video_inputs = {
 	.video_inputs = {
 		{ CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE7 },
 		{ CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE7 },
 		{ CX18_CARD_INPUT_SVIDEO1,    1, CX23418_SVIDEO1    },
 		{ CX18_CARD_INPUT_SVIDEO1,    1, CX23418_SVIDEO1    },
@@ -86,11 +87,12 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
 static const struct cx18_card cx18_card_hvr1600_samsung = {
 static const struct cx18_card cx18_card_hvr1600_samsung = {
 	.type = CX18_CARD_HVR_1600_SAMSUNG,
 	.type = CX18_CARD_HVR_1600_SAMSUNG,
 	.name = "Hauppauge HVR-1600 (Preproduction)",
 	.name = "Hauppauge HVR-1600 (Preproduction)",
-	.comment = "DVB & VBI are not yet supported\n",
+	.comment = "VBI is not yet supported\n",
 	.v4l2_capabilities = CX18_CAP_ENCODER,
 	.v4l2_capabilities = CX18_CAP_ENCODER,
 	.hw_audio_ctrl = CX18_HW_CX23418,
 	.hw_audio_ctrl = CX18_HW_CX23418,
 	.hw_muxer = CX18_HW_CS5345,
 	.hw_muxer = CX18_HW_CS5345,
-	.hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345,
+	.hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
+		  CX18_HW_CS5345 | CX18_HW_DVB,
 	.video_inputs = {
 	.video_inputs = {
 		{ CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE7 },
 		{ CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE7 },
 		{ CX18_CARD_INPUT_SVIDEO1,    1, CX23418_SVIDEO1    },
 		{ CX18_CARD_INPUT_SVIDEO1,    1, CX23418_SVIDEO1    },
@@ -134,14 +136,15 @@ static const struct cx18_card_pci_info cx18_pci_h900[] = {
 static const struct cx18_card cx18_card_h900 = {
 static const struct cx18_card cx18_card_h900 = {
 	.type = CX18_CARD_COMPRO_H900,
 	.type = CX18_CARD_COMPRO_H900,
 	.name = "Compro VideoMate H900",
 	.name = "Compro VideoMate H900",
-	.comment = "Not yet supported!\n",
-	.v4l2_capabilities = 0,
+	.comment = "DVB & VBI are not yet supported\n",
+	.v4l2_capabilities = CX18_CAP_ENCODER,
 	.hw_audio_ctrl = CX18_HW_CX23418,
 	.hw_audio_ctrl = CX18_HW_CX23418,
 	.hw_all = CX18_HW_TUNER,
 	.hw_all = CX18_HW_TUNER,
 	.video_inputs = {
 	.video_inputs = {
-		{ CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE7 },
-		{ CX18_CARD_INPUT_SVIDEO1,    1, CX23418_SVIDEO1    },
-		{ CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
+		{ CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE2 },
+		{ CX18_CARD_INPUT_SVIDEO1,    1,
+			CX23418_SVIDEO_LUMA3 | CX23418_SVIDEO_CHROMA4 },
+		{ CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE1 },
 	},
 	},
 	.audio_inputs = {
 	.audio_inputs = {
 		{ CX18_CARD_INPUT_AUD_TUNER,
 		{ CX18_CARD_INPUT_AUD_TUNER,
@@ -163,6 +166,7 @@ static const struct cx18_card cx18_card_h900 = {
 		.tune_lane = 0,
 		.tune_lane = 0,
 		.initial_emrs = 0,
 		.initial_emrs = 0,
 	},
 	},
+	.xceive_pin = 15,
 	.pci_list = cx18_pci_h900,
 	.pci_list = cx18_pci_h900,
 	.i2c = &cx18_i2c_std,
 	.i2c = &cx18_i2c_std,
 };
 };
@@ -200,8 +204,6 @@ static const struct cx18_card cx18_card_mpc718 = {
 		/* XC3028 tuner */
 		/* XC3028 tuner */
 		{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
 		{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
 	},
 	},
-	/* tuner reset */
-	.gpio_init = { .direction = 0x1000, .initial_value = 0x1000 },
 	.ddr = {
 	.ddr = {
 		/* Probably Samsung K4D263238G-VC33 memory */
 		/* Probably Samsung K4D263238G-VC33 memory */
 		.chip_config = 0x003,
 		.chip_config = 0x003,
@@ -211,6 +213,7 @@ static const struct cx18_card cx18_card_mpc718 = {
 		.tune_lane = 0,
 		.tune_lane = 0,
 		.initial_emrs = 2,
 		.initial_emrs = 2,
 	},
 	},
+	.xceive_pin = 15,
 	.pci_list = cx18_pci_mpc718,
 	.pci_list = cx18_pci_mpc718,
 	.i2c = &cx18_i2c_std,
 	.i2c = &cx18_i2c_std,
 };
 };

+ 3 - 2
drivers/media/video/cx18/cx18-cards.h

@@ -114,8 +114,8 @@ struct cx18_card_pci_info {
 /* The mask is the set of bits used by the operation */
 /* The mask is the set of bits used by the operation */
 
 
 struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */
 struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */
-	u16 direction; 	/* DIR setting. Leave to 0 if no init is needed */
-	u16 initial_value;
+	u32 direction; 	/* DIR setting. Leave to 0 if no init is needed */
+	u32 initial_value;
 };
 };
 
 
 struct cx18_card_tuner {
 struct cx18_card_tuner {
@@ -153,6 +153,7 @@ struct cx18_card {
 	struct cx18_card_audio_input radio_input;
 	struct cx18_card_audio_input radio_input;
 
 
 	/* GPIO card-specific settings */
 	/* GPIO card-specific settings */
+	u8 xceive_pin; 		/* XCeive tuner GPIO reset pin */
 	struct cx18_gpio_init 		gpio_init;
 	struct cx18_gpio_init 		gpio_init;
 
 
 	struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS];
 	struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS];

+ 11 - 18
drivers/media/video/cx18/cx18-driver.c

@@ -164,16 +164,6 @@ MODULE_LICENSE("GPL");
 
 
 MODULE_VERSION(CX18_VERSION);
 MODULE_VERSION(CX18_VERSION);
 
 
-int cx18_waitq(wait_queue_head_t *waitq)
-{
-	DEFINE_WAIT(wait);
-
-	prepare_to_wait(waitq, &wait, TASK_INTERRUPTIBLE);
-	schedule();
-	finish_wait(waitq, &wait);
-	return signal_pending(current) ? -EINTR : 0;
-}
-
 /* Generic utility functions */
 /* Generic utility functions */
 int cx18_msleep_timeout(unsigned int msecs, int intr)
 int cx18_msleep_timeout(unsigned int msecs, int intr)
 {
 {
@@ -220,13 +210,13 @@ static void cx18_process_eeprom(struct cx18 *cx)
 
 
 	/* Many thanks to Steven Toth from Hauppauge for providing the
 	/* Many thanks to Steven Toth from Hauppauge for providing the
 	   model numbers */
 	   model numbers */
+	/* Note: the Samsung memory models cannot be reliably determined
+	   from the model number. Use the cardtype module option if you
+	   have one of these preproduction models. */
 	switch (tv.model) {
 	switch (tv.model) {
-	case 74000 ... 74099:
+	case 74000 ... 74999:
 		cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
 		cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
 		break;
 		break;
-	case 74700 ... 74799:
-		cx->card = cx18_get_card(CX18_CARD_HVR_1600_SAMSUNG);
-		break;
 	case 0:
 	case 0:
 		CX18_ERR("Invalid EEPROM\n");
 		CX18_ERR("Invalid EEPROM\n");
 		return;
 		return;
@@ -548,6 +538,7 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev,
 	return 0;
 	return 0;
 }
 }
 
 
+#ifdef MODULE
 static u32 cx18_request_module(struct cx18 *cx, u32 hw,
 static u32 cx18_request_module(struct cx18 *cx, u32 hw,
 		const char *name, u32 id)
 		const char *name, u32 id)
 {
 {
@@ -560,18 +551,21 @@ static u32 cx18_request_module(struct cx18 *cx, u32 hw,
 	CX18_DEBUG_INFO("Loaded module %s\n", name);
 	CX18_DEBUG_INFO("Loaded module %s\n", name);
 	return hw;
 	return hw;
 }
 }
+#endif
 
 
 static void cx18_load_and_init_modules(struct cx18 *cx)
 static void cx18_load_and_init_modules(struct cx18 *cx)
 {
 {
 	u32 hw = cx->card->hw_all;
 	u32 hw = cx->card->hw_all;
 	int i;
 	int i;
 
 
+#ifdef MODULE
 	/* load modules */
 	/* load modules */
 #ifndef CONFIG_MEDIA_TUNER
 #ifndef CONFIG_MEDIA_TUNER
 	hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER);
 	hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER);
 #endif
 #endif
 #ifndef CONFIG_VIDEO_CS5345
 #ifndef CONFIG_VIDEO_CS5345
 	hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345);
 	hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345);
+#endif
 #endif
 #endif
 
 
 	/* check which i2c devices are actually found */
 	/* check which i2c devices are actually found */
@@ -801,7 +795,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
 	return 0;
 	return 0;
 
 
 free_streams:
 free_streams:
-	cx18_streams_cleanup(cx);
+	cx18_streams_cleanup(cx, 1);
 free_irq:
 free_irq:
 	free_irq(cx->dev->irq, (void *)cx);
 	free_irq(cx->dev->irq, (void *)cx);
 free_i2c:
 free_i2c:
@@ -904,14 +898,13 @@ static void cx18_remove(struct pci_dev *pci_dev)
 
 
 	cx18_halt_firmware(cx);
 	cx18_halt_firmware(cx);
 
 
-	cx18_streams_cleanup(cx);
+	cx18_streams_cleanup(cx, 1);
 
 
 	exit_cx18_i2c(cx);
 	exit_cx18_i2c(cx);
 
 
 	free_irq(cx->dev->irq, (void *)cx);
 	free_irq(cx->dev->irq, (void *)cx);
 
 
-	if (cx->dev)
-		cx18_iounmap(cx);
+	cx18_iounmap(cx);
 
 
 	release_mem_region(cx->base_addr, CX18_MEM_SIZE);
 	release_mem_region(cx->base_addr, CX18_MEM_SIZE);
 
 

+ 0 - 3
drivers/media/video/cx18/cx18-driver.h

@@ -444,9 +444,6 @@ extern spinlock_t cx18_cards_lock;
 /* Return non-zero if a signal is pending */
 /* Return non-zero if a signal is pending */
 int cx18_msleep_timeout(unsigned int msecs, int intr);
 int cx18_msleep_timeout(unsigned int msecs, int intr);
 
 
-/* Wait on queue, returns -EINTR if interrupted */
-int cx18_waitq(wait_queue_head_t *waitq);
-
 /* Read Hauppauge eeprom */
 /* Read Hauppauge eeprom */
 struct tveeprom; /* forward reference */
 struct tveeprom; /* forward reference */
 void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv);
 void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv);

+ 19 - 21
drivers/media/video/cx18/cx18-dvb.c

@@ -24,25 +24,27 @@
 #include "cx18-streams.h"
 #include "cx18-streams.h"
 #include "cx18-cards.h"
 #include "cx18-cards.h"
 #include "s5h1409.h"
 #include "s5h1409.h"
-
-/* Wait until the MXL500X driver is merged */
-#ifdef HAVE_MXL500X
-#include "mxl500x.h"
-#endif
+#include "mxl5005s.h"
 
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 
 #define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000
 #define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000
 
 
-#ifdef HAVE_MXL500X
-static struct mxl500x_config hauppauge_hvr1600_tuner = {
-	.delsys    = MXL500x_MODE_ATSC,
-	.octf      = MXL500x_OCTF_CH,
-	.xtal_freq = 16000000,
-	.iflo_freq = 5380000,
-	.ref_freq  = 322800000,
-	.rssi_ena  = MXL_RSSI_ENABLE,
-	.addr      = 0xC6 >> 1,
+static struct mxl5005s_config hauppauge_hvr1600_tuner = {
+	.i2c_address     = 0xC6 >> 1,
+	.if_freq         = IF_FREQ_5380000HZ,
+	.xtal_freq       = CRYSTAL_FREQ_16000000HZ,
+	.agc_mode        = MXL_SINGLE_AGC,
+	.tracking_filter = MXL_TF_C_H,
+	.rssi_enable     = MXL_RSSI_ENABLE,
+	.cap_select      = MXL_CAP_SEL_ENABLE,
+	.div_out         = MXL_DIV_OUT_4,
+	.clock_out       = MXL_CLOCK_OUT_DISABLE,
+	.output_load     = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+	.top		 = MXL5005S_TOP_25P2,
+	.mod_mode        = MXL_DIGITAL_MODE,
+	.if_mode         = MXL_ZERO_IF,
+	.AgcMasterByte   = 0x00,
 };
 };
 
 
 static struct s5h1409_config hauppauge_hvr1600_config = {
 static struct s5h1409_config hauppauge_hvr1600_config = {
@@ -55,7 +57,6 @@ static struct s5h1409_config hauppauge_hvr1600_config = {
 	.mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
 	.mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
 
 
 };
 };
-#endif
 
 
 static int dvb_register(struct cx18_stream *stream);
 static int dvb_register(struct cx18_stream *stream);
 
 
@@ -252,21 +253,18 @@ static int dvb_register(struct cx18_stream *stream)
 	int ret = 0;
 	int ret = 0;
 
 
 	switch (cx->card->type) {
 	switch (cx->card->type) {
-/* Wait until the MXL500X driver is merged */
-#ifdef HAVE_MXL500X
 	case CX18_CARD_HVR_1600_ESMT:
 	case CX18_CARD_HVR_1600_ESMT:
 	case CX18_CARD_HVR_1600_SAMSUNG:
 	case CX18_CARD_HVR_1600_SAMSUNG:
 		dvb->fe = dvb_attach(s5h1409_attach,
 		dvb->fe = dvb_attach(s5h1409_attach,
 			&hauppauge_hvr1600_config,
 			&hauppauge_hvr1600_config,
 			&cx->i2c_adap[0]);
 			&cx->i2c_adap[0]);
 		if (dvb->fe != NULL) {
 		if (dvb->fe != NULL) {
-			dvb_attach(mxl500x_attach, dvb->fe,
-				&hauppauge_hvr1600_tuner,
-				&cx->i2c_adap[0]);
+			dvb_attach(mxl5005s_attach, dvb->fe,
+				&cx->i2c_adap[0],
+				&hauppauge_hvr1600_tuner);
 			ret = 0;
 			ret = 0;
 		}
 		}
 		break;
 		break;
-#endif
 	default:
 	default:
 		/* No Digital Tv Support */
 		/* No Digital Tv Support */
 		break;
 		break;

+ 4 - 2
drivers/media/video/cx18/cx18-fileops.c

@@ -39,7 +39,7 @@
    associated VBI streams are also automatically claimed.
    associated VBI streams are also automatically claimed.
    Possible error returns: -EBUSY if someone else has claimed
    Possible error returns: -EBUSY if someone else has claimed
    the stream or 0 on success. */
    the stream or 0 on success. */
-int cx18_claim_stream(struct cx18_open_id *id, int type)
+static int cx18_claim_stream(struct cx18_open_id *id, int type)
 {
 {
 	struct cx18 *cx = id->cx;
 	struct cx18 *cx = id->cx;
 	struct cx18_stream *s = &cx->streams[type];
 	struct cx18_stream *s = &cx->streams[type];
@@ -87,7 +87,7 @@ int cx18_claim_stream(struct cx18_open_id *id, int type)
 
 
 /* This function releases a previously claimed stream. It will take into
 /* This function releases a previously claimed stream. It will take into
    account associated VBI streams. */
    account associated VBI streams. */
-void cx18_release_stream(struct cx18_stream *s)
+static void cx18_release_stream(struct cx18_stream *s)
 {
 {
 	struct cx18 *cx = s->cx;
 	struct cx18 *cx = s->cx;
 	struct cx18_stream *s_vbi;
 	struct cx18_stream *s_vbi;
@@ -662,6 +662,8 @@ int cx18_v4l2_open(struct inode *inode, struct file *filp)
 	for (x = 0; cx == NULL && x < cx18_cards_active; x++) {
 	for (x = 0; cx == NULL && x < cx18_cards_active; x++) {
 		/* find out which stream this open was on */
 		/* find out which stream this open was on */
 		for (y = 0; y < CX18_MAX_STREAMS; y++) {
 		for (y = 0; y < CX18_MAX_STREAMS; y++) {
+			if (cx18_cards[x] == NULL)
+				continue;
 			s = &cx18_cards[x]->streams[y];
 			s = &cx18_cards[x]->streams[y];
 			if (s->v4l2dev && s->v4l2dev->minor == minor) {
 			if (s->v4l2dev && s->v4l2dev->minor == minor) {
 				cx = cx18_cards[x];
 				cx = cx18_cards[x];

+ 0 - 9
drivers/media/video/cx18/cx18-fileops.h

@@ -34,12 +34,3 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end);
 void cx18_mute(struct cx18 *cx);
 void cx18_mute(struct cx18 *cx);
 void cx18_unmute(struct cx18 *cx);
 void cx18_unmute(struct cx18 *cx);
 
 
-/* Utilities */
-
-/* Try to claim a stream for the filehandle. Return 0 on success,
-   -EBUSY if stream already claimed. Once a stream is claimed, it
-   remains claimed until the associated filehandle is closed. */
-int cx18_claim_stream(struct cx18_open_id *id, int type);
-
-/* Release a previously claimed stream. */
-void cx18_release_stream(struct cx18_stream *s);

+ 36 - 11
drivers/media/video/cx18/cx18-gpio.c

@@ -35,6 +35,9 @@
 #define CX18_REG_GPIO_OUT2   0xc78104
 #define CX18_REG_GPIO_OUT2   0xc78104
 #define CX18_REG_GPIO_DIR2   0xc7810c
 #define CX18_REG_GPIO_DIR2   0xc7810c
 
 
+static u32 gpio_dir;
+static u32 gpio_val;
+
 /*
 /*
  * HVR-1600 GPIO pins, courtesy of Hauppauge:
  * HVR-1600 GPIO pins, courtesy of Hauppauge:
  *
  *
@@ -44,31 +47,53 @@
  * gpio13: cs5345 reset pin
  * gpio13: cs5345 reset pin
 */
 */
 
 
+static void gpio_write(struct cx18 *cx)
+{
+	write_reg((gpio_dir & 0xffff) << 16, CX18_REG_GPIO_DIR1);
+	write_reg(((gpio_dir & 0xffff) << 16) | (gpio_val & 0xffff),
+			CX18_REG_GPIO_OUT1);
+	write_reg(gpio_dir & 0xffff0000, CX18_REG_GPIO_DIR2);
+	write_reg((gpio_dir & 0xffff0000) | ((gpio_val & 0xffff0000) >> 16),
+			CX18_REG_GPIO_OUT2);
+}
+
 void cx18_gpio_init(struct cx18 *cx)
 void cx18_gpio_init(struct cx18 *cx)
 {
 {
-	if (cx->card->gpio_init.direction == 0)
+	gpio_dir = cx->card->gpio_init.direction;
+	gpio_val = cx->card->gpio_init.initial_value;
+
+	if (gpio_dir == 0)
 		return;
 		return;
 
 
-	CX18_DEBUG_INFO("GPIO initial dir: %08x out: %08x\n",
-		   read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_OUT1));
+	gpio_dir |= 1 << cx->card->xceive_pin;
+	gpio_val |= 1 << cx->card->xceive_pin;
 
 
-	/* init output data then direction */
-	write_reg(cx->card->gpio_init.direction << 16, CX18_REG_GPIO_DIR1);
-	write_reg(0, CX18_REG_GPIO_DIR2);
-	write_reg((cx->card->gpio_init.direction << 16) |
-			cx->card->gpio_init.initial_value, CX18_REG_GPIO_OUT1);
-	write_reg(0, CX18_REG_GPIO_OUT2);
+	CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n",
+		   read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2),
+		   read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2));
+
+	gpio_write(cx);
 }
 }
 
 
 /* Xceive tuner reset function */
 /* Xceive tuner reset function */
 int cx18_reset_tuner_gpio(void *dev, int cmd, int value)
 int cx18_reset_tuner_gpio(void *dev, int cmd, int value)
 {
 {
 	struct i2c_algo_bit_data *algo = dev;
 	struct i2c_algo_bit_data *algo = dev;
-	struct cx18 *cx = algo->data;
-/*	int curdir, curout;*/
+	struct cx18_i2c_algo_callback_data *cb_data = algo->data;
+	struct cx18 *cx = cb_data->cx;
 
 
 	if (cmd != XC2028_TUNER_RESET)
 	if (cmd != XC2028_TUNER_RESET)
 		return 0;
 		return 0;
 	CX18_DEBUG_INFO("Resetting tuner\n");
 	CX18_DEBUG_INFO("Resetting tuner\n");
+
+	gpio_dir |= 1 << cx->card->xceive_pin;
+	gpio_val &= ~(1 << cx->card->xceive_pin);
+
+	gpio_write(cx);
+	schedule_timeout_interruptible(msecs_to_jiffies(1));
+
+	gpio_val |= 1 << cx->card->xceive_pin;
+	gpio_write(cx);
+	schedule_timeout_interruptible(msecs_to_jiffies(1));
 	return 0;
 	return 0;
 }
 }

+ 1 - 0
drivers/media/video/cx18/cx18-i2c.c

@@ -25,6 +25,7 @@
 #include "cx18-cards.h"
 #include "cx18-cards.h"
 #include "cx18-gpio.h"
 #include "cx18-gpio.h"
 #include "cx18-av-core.h"
 #include "cx18-av-core.h"
+#include "cx18-i2c.h"
 
 
 #include <media/ir-kbd-i2c.h>
 #include <media/ir-kbd-i2c.h>
 
 

+ 6 - 16
drivers/media/video/cx18/cx18-queue.c

@@ -26,17 +26,6 @@
 #include "cx18-queue.h"
 #include "cx18-queue.h"
 #include "cx18-scb.h"
 #include "cx18-scb.h"
 
 
-int cx18_buf_copy_from_user(struct cx18_stream *s, struct cx18_buffer *buf,
-		const char __user *src, int copybytes)
-{
-	if (s->buf_size - buf->bytesused < copybytes)
-		copybytes = s->buf_size - buf->bytesused;
-	if (copy_from_user(buf->buf + buf->bytesused, src, copybytes))
-		return -EFAULT;
-	buf->bytesused += copybytes;
-	return copybytes;
-}
-
 void cx18_buf_swap(struct cx18_buffer *buf)
 void cx18_buf_swap(struct cx18_buffer *buf)
 {
 {
 	int i;
 	int i;
@@ -159,8 +148,9 @@ static void cx18_queue_move_buf(struct cx18_stream *s, struct cx18_queue *from,
    -ENOMEM is returned if the buffers could not be obtained, 0 if all
    -ENOMEM is returned if the buffers could not be obtained, 0 if all
    buffers where obtained from the 'from' list and if non-zero then
    buffers where obtained from the 'from' list and if non-zero then
    the number of stolen buffers is returned. */
    the number of stolen buffers is returned. */
-int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
-	struct cx18_queue *steal, struct cx18_queue *to, int needed_bytes)
+static int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
+			   struct cx18_queue *steal, struct cx18_queue *to,
+			   int needed_bytes)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
 	int rc = 0;
 	int rc = 0;
@@ -239,12 +229,12 @@ int cx18_stream_alloc(struct cx18_stream *s)
 
 
 	/* allocate stream buffers. Initially all buffers are in q_free. */
 	/* allocate stream buffers. Initially all buffers are in q_free. */
 	for (i = 0; i < s->buffers; i++) {
 	for (i = 0; i < s->buffers; i++) {
-		struct cx18_buffer *buf =
-			kzalloc(sizeof(struct cx18_buffer), GFP_KERNEL);
+		struct cx18_buffer *buf = kzalloc(sizeof(struct cx18_buffer),
+						GFP_KERNEL|__GFP_NOWARN);
 
 
 		if (buf == NULL)
 		if (buf == NULL)
 			break;
 			break;
-		buf->buf = kmalloc(s->buf_size, GFP_KERNEL);
+		buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN);
 		if (buf->buf == NULL) {
 		if (buf->buf == NULL) {
 			kfree(buf);
 			kfree(buf);
 			break;
 			break;

+ 0 - 4
drivers/media/video/cx18/cx18-queue.h

@@ -39,8 +39,6 @@ static inline void cx18_buf_sync_for_device(struct cx18_stream *s,
 				s->buf_size, s->dma);
 				s->buf_size, s->dma);
 }
 }
 
 
-int cx18_buf_copy_from_user(struct cx18_stream *s, struct cx18_buffer *buf,
-	const char __user *src, int copybytes);
 void cx18_buf_swap(struct cx18_buffer *buf);
 void cx18_buf_swap(struct cx18_buffer *buf);
 
 
 /* cx18_queue utility functions */
 /* cx18_queue utility functions */
@@ -48,8 +46,6 @@ void cx18_queue_init(struct cx18_queue *q);
 void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
 void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
 	struct cx18_queue *q);
 	struct cx18_queue *q);
 struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
 struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
-int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
-       struct cx18_queue *steal, struct cx18_queue *to, int needed_bytes);
 struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id,
 struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id,
 	u32 bytesused);
 	u32 bytesused);
 void cx18_flush_queues(struct cx18_stream *s);
 void cx18_flush_queues(struct cx18_stream *s);

+ 8 - 5
drivers/media/video/cx18/cx18-streams.c

@@ -218,7 +218,7 @@ int cx18_streams_setup(struct cx18 *cx)
 		return 0;
 		return 0;
 
 
 	/* One or more streams could not be initialized. Clean 'em all up. */
 	/* One or more streams could not be initialized. Clean 'em all up. */
-	cx18_streams_cleanup(cx);
+	cx18_streams_cleanup(cx, 0);
 	return -ENOMEM;
 	return -ENOMEM;
 }
 }
 
 
@@ -296,12 +296,12 @@ int cx18_streams_register(struct cx18 *cx)
 		return 0;
 		return 0;
 
 
 	/* One or more streams could not be initialized. Clean 'em all up. */
 	/* One or more streams could not be initialized. Clean 'em all up. */
-	cx18_streams_cleanup(cx);
+	cx18_streams_cleanup(cx, 1);
 	return -ENOMEM;
 	return -ENOMEM;
 }
 }
 
 
 /* Unregister v4l2 devices */
 /* Unregister v4l2 devices */
-void cx18_streams_cleanup(struct cx18 *cx)
+void cx18_streams_cleanup(struct cx18 *cx, int unregister)
 {
 {
 	struct video_device *vdev;
 	struct video_device *vdev;
 	int type;
 	int type;
@@ -319,8 +319,11 @@ void cx18_streams_cleanup(struct cx18 *cx)
 
 
 		cx18_stream_free(&cx->streams[type]);
 		cx18_stream_free(&cx->streams[type]);
 
 
-		/* Unregister device */
-		video_unregister_device(vdev);
+		/* Unregister or release device */
+		if (unregister)
+			video_unregister_device(vdev);
+		else
+			video_device_release(vdev);
 	}
 	}
 }
 }
 
 

+ 1 - 1
drivers/media/video/cx18/cx18-streams.h

@@ -24,7 +24,7 @@
 u32 cx18_find_handle(struct cx18 *cx);
 u32 cx18_find_handle(struct cx18 *cx);
 int cx18_streams_setup(struct cx18 *cx);
 int cx18_streams_setup(struct cx18 *cx);
 int cx18_streams_register(struct cx18 *cx);
 int cx18_streams_register(struct cx18 *cx);
-void cx18_streams_cleanup(struct cx18 *cx);
+void cx18_streams_cleanup(struct cx18 *cx, int unregister);
 
 
 /* Capture related */
 /* Capture related */
 int cx18_start_v4l2_encode_stream(struct cx18_stream *s);
 int cx18_start_v4l2_encode_stream(struct cx18_stream *s);

+ 4 - 2
drivers/media/video/cx23885/Kconfig

@@ -1,18 +1,20 @@
 config VIDEO_CX23885
 config VIDEO_CX23885
 	tristate "Conexant cx23885 (2388x successor) support"
 	tristate "Conexant cx23885 (2388x successor) support"
 	depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT
 	depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT
+	depends on HOTPLUG	# due to FW_LOADER
 	select I2C_ALGOBIT
 	select I2C_ALGOBIT
 	select FW_LOADER
 	select FW_LOADER
 	select VIDEO_BTCX
 	select VIDEO_BTCX
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select VIDEO_TVEEPROM
 	select VIDEO_IR
 	select VIDEO_IR
 	select VIDEOBUF_DVB
 	select VIDEOBUF_DVB
 	select VIDEO_CX25840
 	select VIDEO_CX25840
+	select VIDEO_CX2341X
+	select DVB_DIB7000P if !DVB_FE_CUSTOMISE
 	select MEDIA_TUNER_MT2131 if !DVB_FE_CUSTOMISE
 	select MEDIA_TUNER_MT2131 if !DVB_FE_CUSTOMISE
 	select DVB_S5H1409 if !DVB_FE_CUSTOMISE
 	select DVB_S5H1409 if !DVB_FE_CUSTOMISE
 	select DVB_LGDT330X if !DVB_FE_CUSTOMISE
 	select DVB_LGDT330X if !DVB_FE_CUSTOMISE
-	select DVB_PLL if !DVB_FE_CUSTOMISE
 	select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMIZE
 	select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMIZE
 	select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE
 	select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE
 	select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
 	select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE

+ 35 - 1
drivers/media/video/cx23885/cx23885-cards.c

@@ -198,6 +198,10 @@ struct cx23885_subid cx23885_subids[] = {
 		.subvendor = 0x0070,
 		.subvendor = 0x0070,
 		.subdevice = 0x71d1,
 		.subdevice = 0x71d1,
 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1200,
 		.card      = CX23885_BOARD_HAUPPAUGE_HVR1200,
+	}, {
+		.subvendor = 0x0070,
+		.subdevice = 0x71d3,
+		.card      = CX23885_BOARD_HAUPPAUGE_HVR1200,
 	}, {
 	}, {
 		.subvendor = 0x0070,
 		.subvendor = 0x0070,
 		.subdevice = 0x8101,
 		.subdevice = 0x8101,
@@ -245,6 +249,33 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
 	/* Make sure we support the board model */
 	/* Make sure we support the board model */
 	switch (tv.model)
 	switch (tv.model)
 	{
 	{
+	case 71009:
+		/* WinTV-HVR1200 (PCIe, Retail, full height)
+		 * DVB-T and basic analog */
+	case 71359:
+		/* WinTV-HVR1200 (PCIe, OEM, half height)
+		 * DVB-T and basic analog */
+	case 71439:
+		/* WinTV-HVR1200 (PCIe, OEM, half height)
+		 * DVB-T and basic analog */
+	case 71449:
+		/* WinTV-HVR1200 (PCIe, OEM, full height)
+		 * DVB-T and basic analog */
+	case 71939:
+		/* WinTV-HVR1200 (PCIe, OEM, half height)
+		 * DVB-T and basic analog */
+	case 71949:
+		/* WinTV-HVR1200 (PCIe, OEM, full height)
+		 * DVB-T and basic analog */
+	case 71959:
+		/* WinTV-HVR1200 (PCIe, OEM, full height)
+		 * DVB-T and basic analog */
+	case 71979:
+		/* WinTV-HVR1200 (PCIe, OEM, half height)
+		 * DVB-T and basic analog */
+	case 71999:
+		/* WinTV-HVR1200 (PCIe, OEM, full height)
+		 * DVB-T and basic analog */
 	case 76601: /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual channel ATSC and MPEG2 HW Encoder */
 	case 76601: /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual channel ATSC and MPEG2 HW Encoder */
 	case 77001: /* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC and Basic analog */
 	case 77001: /* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC and Basic analog */
 	case 77011: /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC and Basic analog */
 	case 77011: /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC and Basic analog */
@@ -263,8 +294,11 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
 	case 80019:
 	case 80019:
 		/* WinTV-HVR1400 (Express Card, Retail, IR,
 		/* WinTV-HVR1400 (Express Card, Retail, IR,
 		 * DVB-T and Basic analog */
 		 * DVB-T and Basic analog */
+	case 81509:
+		/* WinTV-HVR1700 (PCIe, OEM, No IR, half height)
+		 * DVB-T and MPEG2 HW Encoder */
 	case 81519:
 	case 81519:
-		/* WinTV-HVR1700 (PCIe, Retail, No IR, half height,
+		/* WinTV-HVR1700 (PCIe, OEM, No IR, full height)
 		 * DVB-T and MPEG2 HW Encoder */
 		 * DVB-T and MPEG2 HW Encoder */
 		break;
 		break;
 	default:
 	default:

+ 2 - 5
drivers/media/video/cx23885/cx23885-dvb.c

@@ -37,7 +37,6 @@
 #include "lgdt330x.h"
 #include "lgdt330x.h"
 #include "xc5000.h"
 #include "xc5000.h"
 #include "tda10048.h"
 #include "tda10048.h"
-#include "dvb-pll.h"
 #include "tuner-xc2028.h"
 #include "tuner-xc2028.h"
 #include "tuner-simple.h"
 #include "tuner-simple.h"
 #include "dib7000p.h"
 #include "dib7000p.h"
@@ -385,12 +384,10 @@ static int dvb_register(struct cx23885_tsport *port)
 		port->dvb.frontend = dvb_attach(s5h1409_attach,
 		port->dvb.frontend = dvb_attach(s5h1409_attach,
 						&hauppauge_hvr1500q_config,
 						&hauppauge_hvr1500q_config,
 						&dev->i2c_bus[0].i2c_adap);
 						&dev->i2c_bus[0].i2c_adap);
-		if (port->dvb.frontend != NULL) {
-			hauppauge_hvr1500q_tunerconfig.priv = i2c_bus;
+		if (port->dvb.frontend != NULL)
 			dvb_attach(xc5000_attach, port->dvb.frontend,
 			dvb_attach(xc5000_attach, port->dvb.frontend,
 				&i2c_bus->i2c_adap,
 				&i2c_bus->i2c_adap,
-				&hauppauge_hvr1500q_tunerconfig);
-		}
+				&hauppauge_hvr1500q_tunerconfig, i2c_bus);
 		break;
 		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1500:
 	case CX23885_BOARD_HAUPPAUGE_HVR1500:
 		i2c_bus = &dev->i2c_bus[1];
 		i2c_bus = &dev->i2c_bus[1];

+ 1 - 0
drivers/media/video/cx25840/Kconfig

@@ -1,6 +1,7 @@
 config VIDEO_CX25840
 config VIDEO_CX25840
 	tristate "Conexant CX2584x audio/video decoders"
 	tristate "Conexant CX2584x audio/video decoders"
 	depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
 	depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+	depends on HOTPLUG # due to FW_LOADER
 	select FW_LOADER
 	select FW_LOADER
 	---help---
 	---help---
 	  Support for the Conexant CX2584x audio/video decoders.
 	  Support for the Conexant CX2584x audio/video decoders.

+ 3 - 3
drivers/media/video/cx88/Kconfig

@@ -2,10 +2,9 @@ config VIDEO_CX88
 	tristate "Conexant 2388x (bt878 successor) support"
 	tristate "Conexant 2388x (bt878 successor) support"
 	depends on VIDEO_DEV && PCI && I2C && INPUT
 	depends on VIDEO_DEV && PCI && I2C && INPUT
 	select I2C_ALGOBIT
 	select I2C_ALGOBIT
-	select FW_LOADER
 	select VIDEO_BTCX
 	select VIDEO_BTCX
 	select VIDEOBUF_DMA_SG
 	select VIDEOBUF_DMA_SG
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select VIDEO_TVEEPROM
 	select VIDEO_IR
 	select VIDEO_IR
 	select VIDEO_WM8775 if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_WM8775 if VIDEO_HELPER_CHIPS_AUTO
@@ -34,8 +33,9 @@ config VIDEO_CX88_ALSA
 
 
 config VIDEO_CX88_BLACKBIRD
 config VIDEO_CX88_BLACKBIRD
 	tristate "Blackbird MPEG encoder support (cx2388x + cx23416)"
 	tristate "Blackbird MPEG encoder support (cx2388x + cx23416)"
-	depends on VIDEO_CX88
+	depends on VIDEO_CX88 && HOTPLUG
 	select VIDEO_CX2341X
 	select VIDEO_CX2341X
+	select FW_LOADER
 	---help---
 	---help---
 	  This adds support for MPEG encoder cards based on the
 	  This adds support for MPEG encoder cards based on the
 	  Blackbird reference design, using the Conexant 2388x
 	  Blackbird reference design, using the Conexant 2388x

+ 134 - 119
drivers/media/video/cx88/cx88-dvb.c

@@ -509,9 +509,6 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
 	if (!fe) {
 	if (!fe) {
 		printk(KERN_ERR "%s/2: xc3028 attach failed\n",
 		printk(KERN_ERR "%s/2: xc3028 attach failed\n",
 		       dev->core->name);
 		       dev->core->name);
-		dvb_frontend_detach(dev->dvb.frontend);
-		dvb_unregister_frontend(dev->dvb.frontend);
-		dev->dvb.frontend = NULL;
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
@@ -523,20 +520,23 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
 
 
 static int dvb_register(struct cx8802_dev *dev)
 static int dvb_register(struct cx8802_dev *dev)
 {
 {
+	struct cx88_core *core = dev->core;
+
 	/* init struct videobuf_dvb */
 	/* init struct videobuf_dvb */
-	dev->dvb.name = dev->core->name;
+	dev->dvb.name = core->name;
 	dev->ts_gen_cntrl = 0x0c;
 	dev->ts_gen_cntrl = 0x0c;
 
 
 	/* init frontend */
 	/* init frontend */
-	switch (dev->core->boardnr) {
+	switch (core->boardnr) {
 	case CX88_BOARD_HAUPPAUGE_DVB_T1:
 	case CX88_BOARD_HAUPPAUGE_DVB_T1:
 		dev->dvb.frontend = dvb_attach(cx22702_attach,
 		dev->dvb.frontend = dvb_attach(cx22702_attach,
 					       &connexant_refboard_config,
 					       &connexant_refboard_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
-				   &dev->core->i2c_adap,
-				   DVB_PLL_THOMSON_DTT759X);
+			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+					0x61, &core->i2c_adap,
+					DVB_PLL_THOMSON_DTT759X))
+				goto frontend_detach;
 		}
 		}
 		break;
 		break;
 	case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
 	case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
@@ -545,11 +545,12 @@ static int dvb_register(struct cx8802_dev *dev)
 	case CX88_BOARD_WINFAST_DTV1000:
 	case CX88_BOARD_WINFAST_DTV1000:
 		dev->dvb.frontend = dvb_attach(cx22702_attach,
 		dev->dvb.frontend = dvb_attach(cx22702_attach,
 					       &connexant_refboard_config,
 					       &connexant_refboard_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
-				   &dev->core->i2c_adap,
-				   DVB_PLL_THOMSON_DTT7579);
+			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+					0x60, &core->i2c_adap,
+					DVB_PLL_THOMSON_DTT7579))
+				goto frontend_detach;
 		}
 		}
 		break;
 		break;
 	case CX88_BOARD_WINFAST_DTV2000H:
 	case CX88_BOARD_WINFAST_DTV2000H:
@@ -559,29 +560,32 @@ static int dvb_register(struct cx8802_dev *dev)
 	case CX88_BOARD_HAUPPAUGE_HVR3000:
 	case CX88_BOARD_HAUPPAUGE_HVR3000:
 		dev->dvb.frontend = dvb_attach(cx22702_attach,
 		dev->dvb.frontend = dvb_attach(cx22702_attach,
 					       &hauppauge_hvr_config,
 					       &hauppauge_hvr_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x61,
-				   TUNER_PHILIPS_FMD1216ME_MK3);
+			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+				   &core->i2c_adap, 0x61,
+				   TUNER_PHILIPS_FMD1216ME_MK3))
+				goto frontend_detach;
 		}
 		}
 		break;
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
 		dev->dvb.frontend = dvb_attach(mt352_attach,
 		dev->dvb.frontend = dvb_attach(mt352_attach,
 					       &dvico_fusionhdtv,
 					       &dvico_fusionhdtv,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
-				   NULL, DVB_PLL_THOMSON_DTT7579);
+			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+					0x60, NULL, DVB_PLL_THOMSON_DTT7579))
+				goto frontend_detach;
 			break;
 			break;
 		}
 		}
 		/* ZL10353 replaces MT352 on later cards */
 		/* ZL10353 replaces MT352 on later cards */
 		dev->dvb.frontend = dvb_attach(zl10353_attach,
 		dev->dvb.frontend = dvb_attach(zl10353_attach,
 					       &dvico_fusionhdtv_plus_v1_1,
 					       &dvico_fusionhdtv_plus_v1_1,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
-				   NULL, DVB_PLL_THOMSON_DTT7579);
+			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+					0x60, NULL, DVB_PLL_THOMSON_DTT7579))
+				goto frontend_detach;
 		}
 		}
 		break;
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
@@ -589,28 +593,31 @@ static int dvb_register(struct cx8802_dev *dev)
 		 * compatible, with a slightly different MT352 AGC gain. */
 		 * compatible, with a slightly different MT352 AGC gain. */
 		dev->dvb.frontend = dvb_attach(mt352_attach,
 		dev->dvb.frontend = dvb_attach(mt352_attach,
 					       &dvico_fusionhdtv_dual,
 					       &dvico_fusionhdtv_dual,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
-				   NULL, DVB_PLL_THOMSON_DTT7579);
+			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+					0x61, NULL, DVB_PLL_THOMSON_DTT7579))
+				goto frontend_detach;
 			break;
 			break;
 		}
 		}
 		/* ZL10353 replaces MT352 on later cards */
 		/* ZL10353 replaces MT352 on later cards */
 		dev->dvb.frontend = dvb_attach(zl10353_attach,
 		dev->dvb.frontend = dvb_attach(zl10353_attach,
 					       &dvico_fusionhdtv_plus_v1_1,
 					       &dvico_fusionhdtv_plus_v1_1,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
-				   NULL, DVB_PLL_THOMSON_DTT7579);
+			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+					0x61, NULL, DVB_PLL_THOMSON_DTT7579))
+				goto frontend_detach;
 		}
 		}
 		break;
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
 		dev->dvb.frontend = dvb_attach(mt352_attach,
 		dev->dvb.frontend = dvb_attach(mt352_attach,
 					       &dvico_fusionhdtv,
 					       &dvico_fusionhdtv,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
-				   NULL, DVB_PLL_LG_Z201);
+			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+					0x61, NULL, DVB_PLL_LG_Z201))
+				goto frontend_detach;
 		}
 		}
 		break;
 		break;
 	case CX88_BOARD_KWORLD_DVB_T:
 	case CX88_BOARD_KWORLD_DVB_T:
@@ -618,10 +625,11 @@ static int dvb_register(struct cx8802_dev *dev)
 	case CX88_BOARD_ADSTECH_DVB_T_PCI:
 	case CX88_BOARD_ADSTECH_DVB_T_PCI:
 		dev->dvb.frontend = dvb_attach(mt352_attach,
 		dev->dvb.frontend = dvb_attach(mt352_attach,
 					       &dntv_live_dvbt_config,
 					       &dntv_live_dvbt_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
-				   NULL, DVB_PLL_UNKNOWN_1);
+			if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+					0x61, NULL, DVB_PLL_UNKNOWN_1))
+				goto frontend_detach;
 		}
 		}
 		break;
 		break;
 	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
 	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
@@ -630,32 +638,35 @@ static int dvb_register(struct cx8802_dev *dev)
 		dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
 		dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
 					       &dev->vp3054->adap);
 					       &dev->vp3054->adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x61,
-				   TUNER_PHILIPS_FMD1216ME_MK3);
+			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+					&core->i2c_adap, 0x61,
+					TUNER_PHILIPS_FMD1216ME_MK3))
+				goto frontend_detach;
 		}
 		}
 #else
 #else
-		printk(KERN_ERR "%s/2: built without vp3054 support\n", dev->core->name);
+		printk(KERN_ERR "%s/2: built without vp3054 support\n",
+				core->name);
 #endif
 #endif
 		break;
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
 		dev->dvb.frontend = dvb_attach(zl10353_attach,
 		dev->dvb.frontend = dvb_attach(zl10353_attach,
 					       &dvico_fusionhdtv_hybrid,
 					       &dvico_fusionhdtv_hybrid,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x61,
-				   TUNER_THOMSON_FE6600);
+			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+				   &core->i2c_adap, 0x61,
+				   TUNER_THOMSON_FE6600))
+				goto frontend_detach;
 		}
 		}
 		break;
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
 		dev->dvb.frontend = dvb_attach(zl10353_attach,
 		dev->dvb.frontend = dvb_attach(zl10353_attach,
 					       &dvico_fusionhdtv_xc3028,
 					       &dvico_fusionhdtv_xc3028,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend == NULL)
 		if (dev->dvb.frontend == NULL)
 			dev->dvb.frontend = dvb_attach(mt352_attach,
 			dev->dvb.frontend = dvb_attach(mt352_attach,
 						&dvico_fusionhdtv_mt352_xc3028,
 						&dvico_fusionhdtv_mt352_xc3028,
-						&dev->core->i2c_adap);
+						&core->i2c_adap);
 		/*
 		/*
 		 * On this board, the demod provides the I2C bus pullup.
 		 * On this board, the demod provides the I2C bus pullup.
 		 * We must not permit gate_ctrl to be performed, or
 		 * We must not permit gate_ctrl to be performed, or
@@ -668,19 +679,18 @@ static int dvb_register(struct cx8802_dev *dev)
 		break;
 		break;
 	case CX88_BOARD_PCHDTV_HD3000:
 	case CX88_BOARD_PCHDTV_HD3000:
 		dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
 		dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x61,
-				   TUNER_THOMSON_DTT761X);
+			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+					&core->i2c_adap, 0x61,
+					TUNER_THOMSON_DTT761X))
+				goto frontend_detach;
 		}
 		}
 		break;
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
 	case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
 		dev->ts_gen_cntrl = 0x08;
 		dev->ts_gen_cntrl = 0x08;
-		{
-		/* Do a hardware reset of chip before using it. */
-		struct cx88_core *core = dev->core;
 
 
+		/* Do a hardware reset of chip before using it. */
 		cx_clear(MO_GP0_IO, 1);
 		cx_clear(MO_GP0_IO, 1);
 		mdelay(100);
 		mdelay(100);
 		cx_set(MO_GP0_IO, 1);
 		cx_set(MO_GP0_IO, 1);
@@ -690,139 +700,137 @@ static int dvb_register(struct cx8802_dev *dev)
 		fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
 		fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
 		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
 		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
 					       &fusionhdtv_3_gold,
 					       &fusionhdtv_3_gold,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x61,
-				   TUNER_MICROTUNE_4042FI5);
-		}
+			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+					&core->i2c_adap, 0x61,
+					TUNER_MICROTUNE_4042FI5))
+				goto frontend_detach;
 		}
 		}
 		break;
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
 	case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
 		dev->ts_gen_cntrl = 0x08;
 		dev->ts_gen_cntrl = 0x08;
-		{
-		/* Do a hardware reset of chip before using it. */
-		struct cx88_core *core = dev->core;
 
 
+		/* Do a hardware reset of chip before using it. */
 		cx_clear(MO_GP0_IO, 1);
 		cx_clear(MO_GP0_IO, 1);
 		mdelay(100);
 		mdelay(100);
 		cx_set(MO_GP0_IO, 9);
 		cx_set(MO_GP0_IO, 9);
 		mdelay(200);
 		mdelay(200);
 		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
 		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
 					       &fusionhdtv_3_gold,
 					       &fusionhdtv_3_gold,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x61,
-				   TUNER_THOMSON_DTT761X);
-		}
+			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+					&core->i2c_adap, 0x61,
+					TUNER_THOMSON_DTT761X))
+				goto frontend_detach;
 		}
 		}
 		break;
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
 	case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
 		dev->ts_gen_cntrl = 0x08;
 		dev->ts_gen_cntrl = 0x08;
-		{
-		/* Do a hardware reset of chip before using it. */
-		struct cx88_core *core = dev->core;
 
 
+		/* Do a hardware reset of chip before using it. */
 		cx_clear(MO_GP0_IO, 1);
 		cx_clear(MO_GP0_IO, 1);
 		mdelay(100);
 		mdelay(100);
 		cx_set(MO_GP0_IO, 1);
 		cx_set(MO_GP0_IO, 1);
 		mdelay(200);
 		mdelay(200);
 		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
 		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
 					       &fusionhdtv_5_gold,
 					       &fusionhdtv_5_gold,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x61,
-				   TUNER_LG_TDVS_H06XF);
-			dvb_attach(tda9887_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x43);
-		}
+			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+					&core->i2c_adap, 0x61,
+					TUNER_LG_TDVS_H06XF))
+				goto frontend_detach;
+			if (!dvb_attach(tda9887_attach, dev->dvb.frontend,
+				   &core->i2c_adap, 0x43))
+				goto frontend_detach;
 		}
 		}
 		break;
 		break;
 	case CX88_BOARD_PCHDTV_HD5500:
 	case CX88_BOARD_PCHDTV_HD5500:
 		dev->ts_gen_cntrl = 0x08;
 		dev->ts_gen_cntrl = 0x08;
-		{
-		/* Do a hardware reset of chip before using it. */
-		struct cx88_core *core = dev->core;
 
 
+		/* Do a hardware reset of chip before using it. */
 		cx_clear(MO_GP0_IO, 1);
 		cx_clear(MO_GP0_IO, 1);
 		mdelay(100);
 		mdelay(100);
 		cx_set(MO_GP0_IO, 1);
 		cx_set(MO_GP0_IO, 1);
 		mdelay(200);
 		mdelay(200);
 		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
 		dev->dvb.frontend = dvb_attach(lgdt330x_attach,
 					       &pchdtv_hd5500,
 					       &pchdtv_hd5500,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x61,
-				   TUNER_LG_TDVS_H06XF);
-			dvb_attach(tda9887_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x43);
-		}
+			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+					&core->i2c_adap, 0x61,
+					TUNER_LG_TDVS_H06XF))
+				goto frontend_detach;
+			if (!dvb_attach(tda9887_attach, dev->dvb.frontend,
+				   &core->i2c_adap, 0x43))
+				goto frontend_detach;
 		}
 		}
 		break;
 		break;
 	case CX88_BOARD_ATI_HDTVWONDER:
 	case CX88_BOARD_ATI_HDTVWONDER:
 		dev->dvb.frontend = dvb_attach(nxt200x_attach,
 		dev->dvb.frontend = dvb_attach(nxt200x_attach,
 					       &ati_hdtvwonder,
 					       &ati_hdtvwonder,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
-			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x61,
-				   TUNER_PHILIPS_TUV1236D);
+			if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+					&core->i2c_adap, 0x61,
+					TUNER_PHILIPS_TUV1236D))
+				goto frontend_detach;
 		}
 		}
 		break;
 		break;
 	case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
 	case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
 	case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
 	case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
 		dev->dvb.frontend = dvb_attach(cx24123_attach,
 		dev->dvb.frontend = dvb_attach(cx24123_attach,
 					       &hauppauge_novas_config,
 					       &hauppauge_novas_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend) {
 		if (dev->dvb.frontend) {
-			dvb_attach(isl6421_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap, 0x08, 0x00, 0x00);
+			if (!dvb_attach(isl6421_attach, dev->dvb.frontend,
+					&core->i2c_adap, 0x08, 0x00, 0x00))
+				goto frontend_detach;
 		}
 		}
 		break;
 		break;
 	case CX88_BOARD_KWORLD_DVBS_100:
 	case CX88_BOARD_KWORLD_DVBS_100:
 		dev->dvb.frontend = dvb_attach(cx24123_attach,
 		dev->dvb.frontend = dvb_attach(cx24123_attach,
 					       &kworld_dvbs_100_config,
 					       &kworld_dvbs_100_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend) {
 		if (dev->dvb.frontend) {
-			dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
+			core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
 			dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
 			dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
 		}
 		}
 		break;
 		break;
 	case CX88_BOARD_GENIATECH_DVBS:
 	case CX88_BOARD_GENIATECH_DVBS:
 		dev->dvb.frontend = dvb_attach(cx24123_attach,
 		dev->dvb.frontend = dvb_attach(cx24123_attach,
 					       &geniatech_dvbs_config,
 					       &geniatech_dvbs_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend) {
 		if (dev->dvb.frontend) {
-			dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
+			core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
 			dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
 			dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
 		}
 		}
 		break;
 		break;
 	case CX88_BOARD_PINNACLE_PCTV_HD_800i:
 	case CX88_BOARD_PINNACLE_PCTV_HD_800i:
 		dev->dvb.frontend = dvb_attach(s5h1409_attach,
 		dev->dvb.frontend = dvb_attach(s5h1409_attach,
 					       &pinnacle_pctv_hd_800i_config,
 					       &pinnacle_pctv_hd_800i_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
 			/* tuner_config.video_dev must point to
 			/* tuner_config.video_dev must point to
 			 * i2c_adap.algo_data
 			 * i2c_adap.algo_data
 			 */
 			 */
-			pinnacle_pctv_hd_800i_tuner_config.priv =
-						dev->core->i2c_adap.algo_data;
-			dvb_attach(xc5000_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap,
-				   &pinnacle_pctv_hd_800i_tuner_config);
+			if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
+					&core->i2c_adap,
+					&pinnacle_pctv_hd_800i_tuner_config,
+					core->i2c_adap.algo_data))
+				goto frontend_detach;
 		}
 		}
 		break;
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
 	case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
 		dev->dvb.frontend = dvb_attach(s5h1409_attach,
 		dev->dvb.frontend = dvb_attach(s5h1409_attach,
 						&dvico_hdtv5_pci_nano_config,
 						&dvico_hdtv5_pci_nano_config,
-						&dev->core->i2c_adap);
+						&core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
 			struct dvb_frontend *fe;
 			struct dvb_frontend *fe;
 			struct xc2028_config cfg = {
 			struct xc2028_config cfg = {
-				.i2c_adap  = &dev->core->i2c_adap,
+				.i2c_adap  = &core->i2c_adap,
 				.i2c_addr  = 0x61,
 				.i2c_addr  = 0x61,
 				.callback  = cx88_pci_nano_callback,
 				.callback  = cx88_pci_nano_callback,
 			};
 			};
@@ -841,50 +849,50 @@ static int dvb_register(struct cx8802_dev *dev)
 	 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
 	 case CX88_BOARD_PINNACLE_HYBRID_PCTV:
 		dev->dvb.frontend = dvb_attach(zl10353_attach,
 		dev->dvb.frontend = dvb_attach(zl10353_attach,
 					       &cx88_geniatech_x8000_mt,
 					       &cx88_geniatech_x8000_mt,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (attach_xc3028(0x61, dev) < 0)
 		if (attach_xc3028(0x61, dev) < 0)
-			return -EINVAL;
+			goto frontend_detach;
 		break;
 		break;
 	 case CX88_BOARD_GENIATECH_X8000_MT:
 	 case CX88_BOARD_GENIATECH_X8000_MT:
 		dev->ts_gen_cntrl = 0x00;
 		dev->ts_gen_cntrl = 0x00;
 
 
 		dev->dvb.frontend = dvb_attach(zl10353_attach,
 		dev->dvb.frontend = dvb_attach(zl10353_attach,
 					       &cx88_geniatech_x8000_mt,
 					       &cx88_geniatech_x8000_mt,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (attach_xc3028(0x61, dev) < 0)
 		if (attach_xc3028(0x61, dev) < 0)
-			return -EINVAL;
+			goto frontend_detach;
 		break;
 		break;
 	 case CX88_BOARD_KWORLD_ATSC_120:
 	 case CX88_BOARD_KWORLD_ATSC_120:
 		dev->dvb.frontend = dvb_attach(s5h1409_attach,
 		dev->dvb.frontend = dvb_attach(s5h1409_attach,
 					       &kworld_atsc_120_config,
 					       &kworld_atsc_120_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (attach_xc3028(0x61, dev) < 0)
 		if (attach_xc3028(0x61, dev) < 0)
-			return -EINVAL;
+			goto frontend_detach;
 		break;
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
 	case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
 		dev->dvb.frontend = dvb_attach(s5h1411_attach,
 		dev->dvb.frontend = dvb_attach(s5h1411_attach,
 					       &dvico_fusionhdtv7_config,
 					       &dvico_fusionhdtv7_config,
-					       &dev->core->i2c_adap);
+					       &core->i2c_adap);
 		if (dev->dvb.frontend != NULL) {
 		if (dev->dvb.frontend != NULL) {
 			/* tuner_config.video_dev must point to
 			/* tuner_config.video_dev must point to
 			 * i2c_adap.algo_data
 			 * i2c_adap.algo_data
 			 */
 			 */
-			dvico_fusionhdtv7_tuner_config.priv =
-						dev->core->i2c_adap.algo_data;
-			dvb_attach(xc5000_attach, dev->dvb.frontend,
-				   &dev->core->i2c_adap,
-				   &dvico_fusionhdtv7_tuner_config);
+			if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
+					&core->i2c_adap,
+					&dvico_fusionhdtv7_tuner_config,
+					core->i2c_adap.algo_data))
+				goto frontend_detach;
 		}
 		}
 		break;
 		break;
 	default:
 	default:
 		printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
 		printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
-		       dev->core->name);
+		       core->name);
 		break;
 		break;
 	}
 	}
 	if (NULL == dev->dvb.frontend) {
 	if (NULL == dev->dvb.frontend) {
 		printk(KERN_ERR
 		printk(KERN_ERR
 		       "%s/2: frontend initialization failed\n",
 		       "%s/2: frontend initialization failed\n",
-		       dev->core->name);
+		       core->name);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
@@ -892,11 +900,18 @@ static int dvb_register(struct cx8802_dev *dev)
 	dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
 	dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
 
 
 	/* Put the analog decoder in standby to keep it quiet */
 	/* Put the analog decoder in standby to keep it quiet */
-	cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
+	cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL);
 
 
 	/* register everything */
 	/* register everything */
 	return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev,
 	return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev,
 				     &dev->pci->dev, adapter_nr);
 				     &dev->pci->dev, adapter_nr);
+
+frontend_detach:
+	if (dev->dvb.frontend) {
+		dvb_frontend_detach(dev->dvb.frontend);
+		dev->dvb.frontend = NULL;
+	}
+	return -EINVAL;
 }
 }
 
 
 /* ----------------------------------------------------------- */
 /* ----------------------------------------------------------- */

+ 1 - 2
drivers/media/video/em28xx/Kconfig

@@ -1,7 +1,7 @@
 config VIDEO_EM28XX
 config VIDEO_EM28XX
 	tristate "Empia EM28xx USB video capture support"
 	tristate "Empia EM28xx USB video capture support"
 	depends on VIDEO_DEV && I2C && INPUT
 	depends on VIDEO_DEV && I2C && INPUT
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select VIDEO_TVEEPROM
 	select VIDEO_IR
 	select VIDEO_IR
 	select VIDEOBUF_VMALLOC
 	select VIDEOBUF_VMALLOC
@@ -35,7 +35,6 @@ config VIDEO_EM28XX_DVB
 	select DVB_LGDT330X if !DVB_FE_CUSTOMISE
 	select DVB_LGDT330X if !DVB_FE_CUSTOMISE
 	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
 	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
 	select VIDEOBUF_DVB
 	select VIDEOBUF_DVB
-	select FW_LOADER
 	---help---
 	---help---
 	  This adds support for DVB cards based on the
 	  This adds support for DVB cards based on the
 	  Empiatech em28xx chips.
 	  Empiatech em28xx chips.

+ 7 - 1
drivers/media/video/em28xx/em28xx-cards.c

@@ -420,7 +420,13 @@ struct usb_device_id em28xx_id_table [] = {
 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
 	{ USB_DEVICE(0x2040, 0x6502),
 	{ USB_DEVICE(0x2040, 0x6502),
 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
-	{ USB_DEVICE(0x2040, 0x6513),
+	{ USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */
+			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+	{ USB_DEVICE(0x2040, 0x6517), /* HP  HVR-950 */
+			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+	{ USB_DEVICE(0x2040, 0x651b), /* RP  HVR-950 */
+			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+	{ USB_DEVICE(0x2040, 0x651f), /* HCW HVR-850 */
 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
 			.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
 	{ USB_DEVICE(0x0ccd, 0x0042),
 	{ USB_DEVICE(0x0ccd, 0x0042),
 			.driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS },
 			.driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS },

+ 0 - 1
drivers/media/video/em28xx/em28xx-dvb.c

@@ -251,7 +251,6 @@ static int attach_xc3028(u8 addr, struct em28xx *dev)
 		printk(KERN_ERR "%s/2: xc3028 attach failed\n",
 		printk(KERN_ERR "%s/2: xc3028 attach failed\n",
 		       dev->name);
 		       dev->name);
 		dvb_frontend_detach(dev->dvb->frontend);
 		dvb_frontend_detach(dev->dvb->frontend);
-		dvb_unregister_frontend(dev->dvb->frontend);
 		dev->dvb->frontend = NULL;
 		dev->dvb->frontend = NULL;
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}

+ 3 - 1
drivers/media/video/ivtv/Kconfig

@@ -1,10 +1,12 @@
 config VIDEO_IVTV
 config VIDEO_IVTV
 	tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support"
 	tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support"
 	depends on VIDEO_V4L1 && VIDEO_V4L2 && PCI && I2C && EXPERIMENTAL
 	depends on VIDEO_V4L1 && VIDEO_V4L2 && PCI && I2C && EXPERIMENTAL
+	depends on INPUT   # due to VIDEO_IR
+	depends on HOTPLUG # due to FW_LOADER
 	select I2C_ALGOBIT
 	select I2C_ALGOBIT
 	select FW_LOADER
 	select FW_LOADER
 	select VIDEO_IR
 	select VIDEO_IR
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select VIDEO_TVEEPROM
 	select VIDEO_CX2341X
 	select VIDEO_CX2341X
 	select VIDEO_CX25840
 	select VIDEO_CX25840

+ 2 - 2
drivers/media/video/ivtv/ivtv-controls.c

@@ -181,12 +181,12 @@ static int ivtv_setup_vbi_fmt(struct ivtv *itv, enum v4l2_mpeg_stream_vbi_fmt fm
 		return 0;
 		return 0;
 	}
 	}
 	/* Need sliced data for mpeg insertion */
 	/* Need sliced data for mpeg insertion */
-	if (get_service_set(itv->vbi.sliced_in) == 0) {
+	if (ivtv_get_service_set(itv->vbi.sliced_in) == 0) {
 		if (itv->is_60hz)
 		if (itv->is_60hz)
 			itv->vbi.sliced_in->service_set = V4L2_SLICED_CAPTION_525;
 			itv->vbi.sliced_in->service_set = V4L2_SLICED_CAPTION_525;
 		else
 		else
 			itv->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625;
 			itv->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625;
-		expand_service_set(itv->vbi.sliced_in, itv->is_50hz);
+		ivtv_expand_service_set(itv->vbi.sliced_in, itv->is_50hz);
 	}
 	}
 	return 0;
 	return 0;
 }
 }

+ 6 - 2
drivers/media/video/ivtv/ivtv-driver.c

@@ -853,6 +853,7 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
 	return 0;
 	return 0;
 }
 }
 
 
+#ifdef MODULE
 static u32 ivtv_request_module(struct ivtv *itv, u32 hw,
 static u32 ivtv_request_module(struct ivtv *itv, u32 hw,
 		const char *name, u32 id)
 		const char *name, u32 id)
 {
 {
@@ -865,12 +866,14 @@ static u32 ivtv_request_module(struct ivtv *itv, u32 hw,
 	IVTV_DEBUG_INFO("Loaded module %s\n", name);
 	IVTV_DEBUG_INFO("Loaded module %s\n", name);
 	return hw;
 	return hw;
 }
 }
+#endif
 
 
 static void ivtv_load_and_init_modules(struct ivtv *itv)
 static void ivtv_load_and_init_modules(struct ivtv *itv)
 {
 {
 	u32 hw = itv->card->hw_all;
 	u32 hw = itv->card->hw_all;
 	unsigned i;
 	unsigned i;
 
 
+#ifdef MODULE
 	/* load modules */
 	/* load modules */
 #ifndef CONFIG_MEDIA_TUNER
 #ifndef CONFIG_MEDIA_TUNER
 	hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER);
 	hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER);
@@ -910,6 +913,7 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
 #endif
 #endif
 #ifndef CONFIG_VIDEO_M52790
 #ifndef CONFIG_VIDEO_M52790
 	hw = ivtv_request_module(itv, hw, "m52790", IVTV_HW_M52790);
 	hw = ivtv_request_module(itv, hw, "m52790", IVTV_HW_M52790);
+#endif
 #endif
 #endif
 
 
 	/* check which i2c devices are actually found */
 	/* check which i2c devices are actually found */
@@ -1228,7 +1232,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
 	return 0;
 	return 0;
 
 
 free_streams:
 free_streams:
-	ivtv_streams_cleanup(itv);
+	ivtv_streams_cleanup(itv, 1);
 free_irq:
 free_irq:
 	free_irq(itv->dev->irq, (void *)itv);
 	free_irq(itv->dev->irq, (void *)itv);
 free_i2c:
 free_i2c:
@@ -1373,7 +1377,7 @@ static void ivtv_remove(struct pci_dev *pci_dev)
 	flush_workqueue(itv->irq_work_queues);
 	flush_workqueue(itv->irq_work_queues);
 	destroy_workqueue(itv->irq_work_queues);
 	destroy_workqueue(itv->irq_work_queues);
 
 
-	ivtv_streams_cleanup(itv);
+	ivtv_streams_cleanup(itv, 1);
 	ivtv_udma_free(itv);
 	ivtv_udma_free(itv);
 
 
 	exit_ivtv_i2c(itv);
 	exit_ivtv_i2c(itv);

+ 2 - 0
drivers/media/video/ivtv/ivtv-fileops.c

@@ -987,6 +987,8 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
 	/* Find which card this open was on */
 	/* Find which card this open was on */
 	spin_lock(&ivtv_cards_lock);
 	spin_lock(&ivtv_cards_lock);
 	for (x = 0; itv == NULL && x < ivtv_cards_active; x++) {
 	for (x = 0; itv == NULL && x < ivtv_cards_active; x++) {
+		if (ivtv_cards[x] == NULL)
+			continue;
 		/* find out which stream this open was on */
 		/* find out which stream this open was on */
 		for (y = 0; y < IVTV_MAX_STREAMS; y++) {
 		for (y = 0; y < IVTV_MAX_STREAMS; y++) {
 			s = &ivtv_cards[x]->streams[y];
 			s = &ivtv_cards[x]->streams[y];

+ 8 - 8
drivers/media/video/ivtv/ivtv-ioctl.c

@@ -38,7 +38,7 @@
 #include <linux/dvb/audio.h>
 #include <linux/dvb/audio.h>
 #include <linux/i2c-id.h>
 #include <linux/i2c-id.h>
 
 
-u16 service2vbi(int type)
+u16 ivtv_service2vbi(int type)
 {
 {
 	switch (type) {
 	switch (type) {
 		case V4L2_SLICED_TELETEXT_B:
 		case V4L2_SLICED_TELETEXT_B:
@@ -88,7 +88,7 @@ static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
 	return 0;
 	return 0;
 }
 }
 
 
-void expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
+void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
 {
 {
 	u16 set = fmt->service_set;
 	u16 set = fmt->service_set;
 	int f, l;
 	int f, l;
@@ -115,7 +115,7 @@ static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
 	return set != 0;
 	return set != 0;
 }
 }
 
 
-u16 get_service_set(struct v4l2_sliced_vbi_format *fmt)
+u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt)
 {
 {
 	int f, l;
 	int f, l;
 	u16 set = 0;
 	u16 set = 0;
@@ -466,7 +466,7 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm
 			vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
 			vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
 			vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
 			vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
 		}
 		}
-		vbifmt->service_set = get_service_set(vbifmt);
+		vbifmt->service_set = ivtv_get_service_set(vbifmt);
 		break;
 		break;
 	}
 	}
 
 
@@ -481,12 +481,12 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm
 		if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
 		if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
 			vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
 			vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
 						 V4L2_SLICED_VBI_525;
 						 V4L2_SLICED_VBI_525;
-			expand_service_set(vbifmt, itv->is_50hz);
+			ivtv_expand_service_set(vbifmt, itv->is_50hz);
 			break;
 			break;
 		}
 		}
 
 
 		itv->video_dec_func(itv, VIDIOC_G_FMT, fmt);
 		itv->video_dec_func(itv, VIDIOC_G_FMT, fmt);
-		vbifmt->service_set = get_service_set(vbifmt);
+		vbifmt->service_set = ivtv_get_service_set(vbifmt);
 		break;
 		break;
 	}
 	}
 	case V4L2_BUF_TYPE_VBI_OUTPUT:
 	case V4L2_BUF_TYPE_VBI_OUTPUT:
@@ -640,9 +640,9 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
 	memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
 	memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
 
 
 	if (vbifmt->service_set)
 	if (vbifmt->service_set)
-		expand_service_set(vbifmt, itv->is_50hz);
+		ivtv_expand_service_set(vbifmt, itv->is_50hz);
 	set = check_service_set(vbifmt, itv->is_50hz);
 	set = check_service_set(vbifmt, itv->is_50hz);
-	vbifmt->service_set = get_service_set(vbifmt);
+	vbifmt->service_set = ivtv_get_service_set(vbifmt);
 
 
 	if (!set_fmt)
 	if (!set_fmt)
 		return 0;
 		return 0;

+ 3 - 3
drivers/media/video/ivtv/ivtv-ioctl.h

@@ -21,9 +21,9 @@
 #ifndef IVTV_IOCTL_H
 #ifndef IVTV_IOCTL_H
 #define IVTV_IOCTL_H
 #define IVTV_IOCTL_H
 
 
-u16 service2vbi(int type);
-void expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
-u16 get_service_set(struct v4l2_sliced_vbi_format *fmt);
+u16 ivtv_service2vbi(int type);
+void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
+u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt);
 int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
 int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
 		    unsigned long arg);
 		    unsigned long arg);
 int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg);
 int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg);

+ 7 - 5
drivers/media/video/ivtv/ivtv-queue.c

@@ -203,14 +203,14 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
 		s->dma != PCI_DMA_NONE ? "DMA " : "",
 		s->dma != PCI_DMA_NONE ? "DMA " : "",
 		s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024);
 		s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024);
 
 
-	s->sg_pending = kzalloc(SGsize, GFP_KERNEL);
+	s->sg_pending = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN);
 	if (s->sg_pending == NULL) {
 	if (s->sg_pending == NULL) {
 		IVTV_ERR("Could not allocate sg_pending for %s stream\n", s->name);
 		IVTV_ERR("Could not allocate sg_pending for %s stream\n", s->name);
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 	s->sg_pending_size = 0;
 	s->sg_pending_size = 0;
 
 
-	s->sg_processing = kzalloc(SGsize, GFP_KERNEL);
+	s->sg_processing = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN);
 	if (s->sg_processing == NULL) {
 	if (s->sg_processing == NULL) {
 		IVTV_ERR("Could not allocate sg_processing for %s stream\n", s->name);
 		IVTV_ERR("Could not allocate sg_processing for %s stream\n", s->name);
 		kfree(s->sg_pending);
 		kfree(s->sg_pending);
@@ -219,7 +219,8 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
 	}
 	}
 	s->sg_processing_size = 0;
 	s->sg_processing_size = 0;
 
 
-	s->sg_dma = kzalloc(sizeof(struct ivtv_sg_element), GFP_KERNEL);
+	s->sg_dma = kzalloc(sizeof(struct ivtv_sg_element),
+					GFP_KERNEL|__GFP_NOWARN);
 	if (s->sg_dma == NULL) {
 	if (s->sg_dma == NULL) {
 		IVTV_ERR("Could not allocate sg_dma for %s stream\n", s->name);
 		IVTV_ERR("Could not allocate sg_dma for %s stream\n", s->name);
 		kfree(s->sg_pending);
 		kfree(s->sg_pending);
@@ -235,11 +236,12 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
 
 
 	/* allocate stream buffers. Initially all buffers are in q_free. */
 	/* allocate stream buffers. Initially all buffers are in q_free. */
 	for (i = 0; i < s->buffers; i++) {
 	for (i = 0; i < s->buffers; i++) {
-		struct ivtv_buffer *buf = kzalloc(sizeof(struct ivtv_buffer), GFP_KERNEL);
+		struct ivtv_buffer *buf = kzalloc(sizeof(struct ivtv_buffer),
+						GFP_KERNEL|__GFP_NOWARN);
 
 
 		if (buf == NULL)
 		if (buf == NULL)
 			break;
 			break;
-		buf->buf = kmalloc(s->buf_size + 256, GFP_KERNEL);
+		buf->buf = kmalloc(s->buf_size + 256, GFP_KERNEL|__GFP_NOWARN);
 		if (buf->buf == NULL) {
 		if (buf->buf == NULL) {
 			kfree(buf);
 			kfree(buf);
 			break;
 			break;

+ 8 - 5
drivers/media/video/ivtv/ivtv-streams.c

@@ -244,7 +244,7 @@ int ivtv_streams_setup(struct ivtv *itv)
 		return 0;
 		return 0;
 
 
 	/* One or more streams could not be initialized. Clean 'em all up. */
 	/* One or more streams could not be initialized. Clean 'em all up. */
-	ivtv_streams_cleanup(itv);
+	ivtv_streams_cleanup(itv, 0);
 	return -ENOMEM;
 	return -ENOMEM;
 }
 }
 
 
@@ -304,12 +304,12 @@ int ivtv_streams_register(struct ivtv *itv)
 		return 0;
 		return 0;
 
 
 	/* One or more streams could not be initialized. Clean 'em all up. */
 	/* One or more streams could not be initialized. Clean 'em all up. */
-	ivtv_streams_cleanup(itv);
+	ivtv_streams_cleanup(itv, 1);
 	return -ENOMEM;
 	return -ENOMEM;
 }
 }
 
 
 /* Unregister v4l2 devices */
 /* Unregister v4l2 devices */
-void ivtv_streams_cleanup(struct ivtv *itv)
+void ivtv_streams_cleanup(struct ivtv *itv, int unregister)
 {
 {
 	int type;
 	int type;
 
 
@@ -322,8 +322,11 @@ void ivtv_streams_cleanup(struct ivtv *itv)
 			continue;
 			continue;
 
 
 		ivtv_stream_free(&itv->streams[type]);
 		ivtv_stream_free(&itv->streams[type]);
-		/* Unregister device */
-		video_unregister_device(vdev);
+		/* Unregister or release device */
+		if (unregister)
+			video_unregister_device(vdev);
+		else
+			video_device_release(vdev);
 	}
 	}
 }
 }
 
 

+ 1 - 1
drivers/media/video/ivtv/ivtv-streams.h

@@ -23,7 +23,7 @@
 
 
 int ivtv_streams_setup(struct ivtv *itv);
 int ivtv_streams_setup(struct ivtv *itv);
 int ivtv_streams_register(struct ivtv *itv);
 int ivtv_streams_register(struct ivtv *itv);
-void ivtv_streams_cleanup(struct ivtv *itv);
+void ivtv_streams_cleanup(struct ivtv *itv, int unregister);
 
 
 /* Capture related */
 /* Capture related */
 int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s);
 int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s);

+ 2 - 1
drivers/media/video/ivtv/ivtv-vbi.c

@@ -169,7 +169,8 @@ static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
 			linemask[0] |= (1 << l);
 			linemask[0] |= (1 << l);
 		else
 		else
 			linemask[1] |= (1 << (l - 32));
 			linemask[1] |= (1 << (l - 32));
-		dst[sd + 12 + line * 43] = service2vbi(itv->vbi.sliced_data[i].id);
+		dst[sd + 12 + line * 43] =
+			ivtv_service2vbi(itv->vbi.sliced_data[i].id);
 		memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42);
 		memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42);
 		line++;
 		line++;
 	}
 	}

+ 1 - 1
drivers/media/video/ivtv/ivtv-yuv.c

@@ -908,7 +908,7 @@ static void ivtv_yuv_init(struct ivtv *itv)
 	}
 	}
 
 
 	/* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
 	/* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
-	yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL);
+	yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL|__GFP_NOWARN);
 	if (yi->blanking_ptr) {
 	if (yi->blanking_ptr) {
 		yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
 		yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
 	} else {
 	} else {

+ 4 - 2
drivers/media/video/ivtv/ivtvfb.c

@@ -948,7 +948,8 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
 	}
 	}
 
 
 	/* Allocate the pseudo palette */
 	/* Allocate the pseudo palette */
-	oi->ivtvfb_info.pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
+	oi->ivtvfb_info.pseudo_palette =
+		kmalloc(sizeof(u32) * 16, GFP_KERNEL|__GFP_NOWARN);
 
 
 	if (!oi->ivtvfb_info.pseudo_palette) {
 	if (!oi->ivtvfb_info.pseudo_palette) {
 		IVTVFB_ERR("abort, unable to alloc pseudo pallete\n");
 		IVTVFB_ERR("abort, unable to alloc pseudo pallete\n");
@@ -1056,7 +1057,8 @@ static int ivtvfb_init_card(struct ivtv *itv)
 		return -EBUSY;
 		return -EBUSY;
 	}
 	}
 
 
-	itv->osd_info = kzalloc(sizeof(struct osd_info), GFP_ATOMIC);
+	itv->osd_info = kzalloc(sizeof(struct osd_info),
+					GFP_ATOMIC|__GFP_NOWARN);
 	if (itv->osd_info == NULL) {
 	if (itv->osd_info == NULL) {
 		IVTVFB_ERR("Failed to allocate memory for osd_info\n");
 		IVTVFB_ERR("Failed to allocate memory for osd_info\n");
 		return -ENOMEM;
 		return -ENOMEM;

+ 1 - 4
drivers/media/video/mt9m001.c

@@ -12,15 +12,12 @@
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/log2.h>
 #include <linux/log2.h>
+#include <linux/gpio.h>
 
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
 #include <media/soc_camera.h>
 
 
-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
-#include <asm/gpio.h>
-#endif
-
 /* mt9m001 i2c address 0x5d
 /* mt9m001 i2c address 0x5d
  * The platform has to define i2c_board_info
  * The platform has to define i2c_board_info
  * and call i2c_register_board_info() */
  * and call i2c_register_board_info() */

+ 2 - 5
drivers/media/video/mt9v022.c

@@ -13,15 +13,12 @@
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/log2.h>
 #include <linux/log2.h>
+#include <linux/gpio.h>
 
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
 #include <media/soc_camera.h>
 
 
-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
-#include <asm/gpio.h>
-#endif
-
 /* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
 /* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
  * The platform has to define i2c_board_info
  * The platform has to define i2c_board_info
  * and call i2c_register_board_info() */
  * and call i2c_register_board_info() */
@@ -91,7 +88,7 @@ static const struct soc_camera_data_format mt9v022_monochrome_formats[] = {
 struct mt9v022 {
 struct mt9v022 {
 	struct i2c_client *client;
 	struct i2c_client *client;
 	struct soc_camera_device icd;
 	struct soc_camera_device icd;
-	int model;	/* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
+	int model;	/* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
 	int switch_gpio;
 	int switch_gpio;
 	u16 chip_control;
 	u16 chip_control;
 	unsigned char datawidth;
 	unsigned char datawidth;

+ 3 - 1
drivers/media/video/pvrusb2/Kconfig

@@ -1,8 +1,10 @@
 config VIDEO_PVRUSB2
 config VIDEO_PVRUSB2
 	tristate "Hauppauge WinTV-PVR USB2 support"
 	tristate "Hauppauge WinTV-PVR USB2 support"
 	depends on VIDEO_V4L2 && I2C
 	depends on VIDEO_V4L2 && I2C
+	depends on VIDEO_MEDIA	# Avoids pvrusb = Y / DVB = M
+	depends on HOTPLUG	# due to FW_LOADER
 	select FW_LOADER
 	select FW_LOADER
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select VIDEO_TVEEPROM
 	select VIDEO_CX2341X
 	select VIDEO_CX2341X
 	select VIDEO_SAA711X
 	select VIDEO_SAA711X

+ 2 - 1
drivers/media/video/saa7134/Kconfig

@@ -3,7 +3,7 @@ config VIDEO_SAA7134
 	depends on VIDEO_DEV && PCI && I2C && INPUT
 	depends on VIDEO_DEV && PCI && I2C && INPUT
 	select VIDEOBUF_DMA_SG
 	select VIDEOBUF_DMA_SG
 	select VIDEO_IR
 	select VIDEO_IR
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
 	select VIDEO_TVEEPROM
 	select CRC32
 	select CRC32
 	---help---
 	---help---
@@ -27,6 +27,7 @@ config VIDEO_SAA7134_ALSA
 config VIDEO_SAA7134_DVB
 config VIDEO_SAA7134_DVB
 	tristate "DVB/ATSC Support for saa7134 based TV cards"
 	tristate "DVB/ATSC Support for saa7134 based TV cards"
 	depends on VIDEO_SAA7134 && DVB_CORE
 	depends on VIDEO_SAA7134 && DVB_CORE
+	depends on HOTPLUG	# due to FW_LOADER
 	select VIDEOBUF_DVB
 	select VIDEOBUF_DVB
 	select FW_LOADER
 	select FW_LOADER
 	select DVB_PLL if !DVB_FE_CUSTOMISE
 	select DVB_PLL if !DVB_FE_CUSTOMISE

+ 0 - 6
drivers/media/video/saa7134/saa7134-core.c

@@ -864,7 +864,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
 	struct saa7134_dev *dev;
 	struct saa7134_dev *dev;
 	struct saa7134_mpeg_ops *mops;
 	struct saa7134_mpeg_ops *mops;
 	int err;
 	int err;
-	int mask;
 
 
 	if (saa7134_devcount == SAA7134_MAXBOARDS)
 	if (saa7134_devcount == SAA7134_MAXBOARDS)
 		return -ENOMEM;
 		return -ENOMEM;
@@ -1065,11 +1064,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
 	if (TUNER_ABSENT != dev->tuner_type)
 	if (TUNER_ABSENT != dev->tuner_type)
 		saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
 		saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
 
 
-	if (card(dev).gpiomask != 0) {
-		mask = card(dev).gpiomask;
-		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   mask, mask);
-		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, 0);
-	}
 	return 0;
 	return 0;
 
 
  fail4:
  fail4:

+ 100 - 40
drivers/media/video/saa7134/saa7134-dvb.c

@@ -538,19 +538,23 @@ static int philips_tda827x_tuner_sleep(struct dvb_frontend *fe)
 	return 0;
 	return 0;
 }
 }
 
 
-static void configure_tda827x_fe(struct saa7134_dev *dev, struct tda1004x_config *cdec_conf,
-							  struct tda827x_config *tuner_conf)
+static int configure_tda827x_fe(struct saa7134_dev *dev,
+				struct tda1004x_config *cdec_conf,
+				struct tda827x_config *tuner_conf)
 {
 {
 	dev->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap);
 	dev->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap);
 	if (dev->dvb.frontend) {
 	if (dev->dvb.frontend) {
 		if (cdec_conf->i2c_gate)
 		if (cdec_conf->i2c_gate)
 			dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
 			dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
-		if (dvb_attach(tda827x_attach, dev->dvb.frontend, cdec_conf->tuner_address,
-							&dev->i2c_adap, tuner_conf) == NULL) {
-			wprintk("no tda827x tuner found at addr: %02x\n",
+		if (dvb_attach(tda827x_attach, dev->dvb.frontend,
+			       cdec_conf->tuner_address,
+			       &dev->i2c_adap, tuner_conf))
+			return 0;
+
+		wprintk("no tda827x tuner found at addr: %02x\n",
 				cdec_conf->tuner_address);
 				cdec_conf->tuner_address);
-		}
 	}
 	}
+	return -EINVAL;
 }
 }
 
 
 /* ------------------------------------------------------------------ */
 /* ------------------------------------------------------------------ */
@@ -997,7 +1001,9 @@ static int dvb_init(struct saa7134_dev *dev)
 		break;
 		break;
 	case SAA7134_BOARD_FLYDVBTDUO:
 	case SAA7134_BOARD_FLYDVBTDUO:
 	case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS:
 	case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS:
-		configure_tda827x_fe(dev, &tda827x_lifeview_config, &tda827x_cfg_0);
+		if (configure_tda827x_fe(dev, &tda827x_lifeview_config,
+					 &tda827x_cfg_0) < 0)
+			goto dettach_frontend;
 		break;
 		break;
 	case SAA7134_BOARD_PHILIPS_EUROPA:
 	case SAA7134_BOARD_PHILIPS_EUROPA:
 	case SAA7134_BOARD_VIDEOMATE_DVBT_300:
 	case SAA7134_BOARD_VIDEOMATE_DVBT_300:
@@ -1022,36 +1028,52 @@ static int dvb_init(struct saa7134_dev *dev)
 		}
 		}
 		break;
 		break;
 	case SAA7134_BOARD_KWORLD_DVBT_210:
 	case SAA7134_BOARD_KWORLD_DVBT_210:
-		configure_tda827x_fe(dev, &kworld_dvb_t_210_config, &tda827x_cfg_2);
+		if (configure_tda827x_fe(dev, &kworld_dvb_t_210_config,
+					 &tda827x_cfg_2) < 0)
+			goto dettach_frontend;
 		break;
 		break;
 	case SAA7134_BOARD_PHILIPS_TIGER:
 	case SAA7134_BOARD_PHILIPS_TIGER:
-		configure_tda827x_fe(dev, &philips_tiger_config, &tda827x_cfg_0);
+		if (configure_tda827x_fe(dev, &philips_tiger_config,
+					 &tda827x_cfg_0) < 0)
+			goto dettach_frontend;
 		break;
 		break;
 	case SAA7134_BOARD_PINNACLE_PCTV_310i:
 	case SAA7134_BOARD_PINNACLE_PCTV_310i:
-		configure_tda827x_fe(dev, &pinnacle_pctv_310i_config, &tda827x_cfg_1);
+		if (configure_tda827x_fe(dev, &pinnacle_pctv_310i_config,
+					 &tda827x_cfg_1) < 0)
+			goto dettach_frontend;
 		break;
 		break;
 	case SAA7134_BOARD_HAUPPAUGE_HVR1110:
 	case SAA7134_BOARD_HAUPPAUGE_HVR1110:
-		configure_tda827x_fe(dev, &hauppauge_hvr_1110_config, &tda827x_cfg_1);
+		if (configure_tda827x_fe(dev, &hauppauge_hvr_1110_config,
+					 &tda827x_cfg_1) < 0)
+			goto dettach_frontend;
 		break;
 		break;
 	case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
 	case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
-		configure_tda827x_fe(dev, &asus_p7131_dual_config, &tda827x_cfg_0);
+		if (configure_tda827x_fe(dev, &asus_p7131_dual_config,
+					 &tda827x_cfg_0) < 0)
+			goto dettach_frontend;
 		break;
 		break;
 	case SAA7134_BOARD_FLYDVBT_LR301:
 	case SAA7134_BOARD_FLYDVBT_LR301:
-		configure_tda827x_fe(dev, &tda827x_lifeview_config, &tda827x_cfg_0);
+		if (configure_tda827x_fe(dev, &tda827x_lifeview_config,
+					 &tda827x_cfg_0) < 0)
+			goto dettach_frontend;
 		break;
 		break;
 	case SAA7134_BOARD_FLYDVB_TRIO:
 	case SAA7134_BOARD_FLYDVB_TRIO:
-		if(! use_frontend) {	/* terrestrial */
-			configure_tda827x_fe(dev, &lifeview_trio_config, &tda827x_cfg_0);
+		if (!use_frontend) {	/* terrestrial */
+			if (configure_tda827x_fe(dev, &lifeview_trio_config,
+						 &tda827x_cfg_0) < 0)
+				goto dettach_frontend;
 		} else {  		/* satellite */
 		} else {  		/* satellite */
 			dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
 			dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
 			if (dev->dvb.frontend) {
 			if (dev->dvb.frontend) {
 				if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63,
 				if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63,
 									&dev->i2c_adap, 0) == NULL) {
 									&dev->i2c_adap, 0) == NULL) {
 					wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__);
 					wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__);
+					goto dettach_frontend;
 				}
 				}
 				if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap,
 				if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap,
 										0x08, 0, 0) == NULL) {
 										0x08, 0, 0) == NULL) {
 					wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__);
 					wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__);
+					goto dettach_frontend;
 				}
 				}
 			}
 			}
 		}
 		}
@@ -1067,15 +1089,20 @@ static int dvb_init(struct saa7134_dev *dev)
 								&ads_duo_cfg) == NULL) {
 								&ads_duo_cfg) == NULL) {
 				wprintk("no tda827x tuner found at addr: %02x\n",
 				wprintk("no tda827x tuner found at addr: %02x\n",
 					ads_tech_duo_config.tuner_address);
 					ads_tech_duo_config.tuner_address);
+				goto dettach_frontend;
 			}
 			}
 		}
 		}
 		break;
 		break;
 	case SAA7134_BOARD_TEVION_DVBT_220RF:
 	case SAA7134_BOARD_TEVION_DVBT_220RF:
-		configure_tda827x_fe(dev, &tevion_dvbt220rf_config, &tda827x_cfg_0);
+		if (configure_tda827x_fe(dev, &tevion_dvbt220rf_config,
+					 &tda827x_cfg_0) < 0)
+			goto dettach_frontend;
 		break;
 		break;
 	case SAA7134_BOARD_MEDION_MD8800_QUADRO:
 	case SAA7134_BOARD_MEDION_MD8800_QUADRO:
 		if (!use_frontend) {     /* terrestrial */
 		if (!use_frontend) {     /* terrestrial */
-			configure_tda827x_fe(dev, &md8800_dvbt_config, &tda827x_cfg_0);
+			if (configure_tda827x_fe(dev, &md8800_dvbt_config,
+						 &tda827x_cfg_0) < 0)
+				goto dettach_frontend;
 		} else {        /* satellite */
 		} else {        /* satellite */
 			dev->dvb.frontend = dvb_attach(tda10086_attach,
 			dev->dvb.frontend = dvb_attach(tda10086_attach,
 							&flydvbs, &dev->i2c_adap);
 							&flydvbs, &dev->i2c_adap);
@@ -1086,16 +1113,20 @@ static int dvb_init(struct saa7134_dev *dev)
 				struct i2c_msg msg = {.addr = 0x08, .flags = 0, .len = 1};
 				struct i2c_msg msg = {.addr = 0x08, .flags = 0, .len = 1};
 
 
 				if (dvb_attach(tda826x_attach, dev->dvb.frontend,
 				if (dvb_attach(tda826x_attach, dev->dvb.frontend,
-						0x60, &dev->i2c_adap, 0) == NULL)
+						0x60, &dev->i2c_adap, 0) == NULL) {
 					wprintk("%s: Medion Quadro, no tda826x "
 					wprintk("%s: Medion Quadro, no tda826x "
 						"found !\n", __func__);
 						"found !\n", __func__);
+					goto dettach_frontend;
+				}
 				if (dev_id != 0x08) {
 				if (dev_id != 0x08) {
 					/* we need to open the i2c gate (we know it exists) */
 					/* we need to open the i2c gate (we know it exists) */
 					fe->ops.i2c_gate_ctrl(fe, 1);
 					fe->ops.i2c_gate_ctrl(fe, 1);
 					if (dvb_attach(isl6405_attach, fe,
 					if (dvb_attach(isl6405_attach, fe,
-							&dev->i2c_adap, 0x08, 0, 0) == NULL)
+							&dev->i2c_adap, 0x08, 0, 0) == NULL) {
 						wprintk("%s: Medion Quadro, no ISL6405 "
 						wprintk("%s: Medion Quadro, no ISL6405 "
 							"found !\n", __func__);
 							"found !\n", __func__);
+						goto dettach_frontend;
+					}
 					if (dev_id == 0x07) {
 					if (dev_id == 0x07) {
 						/* fire up the 2nd section of the LNB supply since
 						/* fire up the 2nd section of the LNB supply since
 						   we can't do this from the other section */
 						   we can't do this from the other section */
@@ -1117,19 +1148,17 @@ static int dvb_init(struct saa7134_dev *dev)
 	case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
 	case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
 		dev->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180,
 		dev->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180,
 					       &dev->i2c_adap);
 					       &dev->i2c_adap);
-		if (dev->dvb.frontend) {
+		if (dev->dvb.frontend)
 			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
 			dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
 				   NULL, DVB_PLL_TDHU2);
 				   NULL, DVB_PLL_TDHU2);
-		}
 		break;
 		break;
 	case SAA7134_BOARD_KWORLD_ATSC110:
 	case SAA7134_BOARD_KWORLD_ATSC110:
 		dev->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110,
 		dev->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110,
 					       &dev->i2c_adap);
 					       &dev->i2c_adap);
-		if (dev->dvb.frontend) {
+		if (dev->dvb.frontend)
 			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
 			dvb_attach(simple_tuner_attach, dev->dvb.frontend,
 				   &dev->i2c_adap, 0x61,
 				   &dev->i2c_adap, 0x61,
 				   TUNER_PHILIPS_TUV1236D);
 				   TUNER_PHILIPS_TUV1236D);
-		}
 		break;
 		break;
 	case SAA7134_BOARD_FLYDVBS_LR300:
 	case SAA7134_BOARD_FLYDVBS_LR300:
 		dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
 		dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
@@ -1138,10 +1167,12 @@ static int dvb_init(struct saa7134_dev *dev)
 			if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
 			if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
 				       &dev->i2c_adap, 0) == NULL) {
 				       &dev->i2c_adap, 0) == NULL) {
 				wprintk("%s: No tda826x found!\n", __func__);
 				wprintk("%s: No tda826x found!\n", __func__);
+				goto dettach_frontend;
 			}
 			}
 			if (dvb_attach(isl6421_attach, dev->dvb.frontend,
 			if (dvb_attach(isl6421_attach, dev->dvb.frontend,
 				       &dev->i2c_adap, 0x08, 0, 0) == NULL) {
 				       &dev->i2c_adap, 0x08, 0, 0) == NULL) {
 				wprintk("%s: No ISL6421 found!\n", __func__);
 				wprintk("%s: No ISL6421 found!\n", __func__);
+				goto dettach_frontend;
 			}
 			}
 		}
 		}
 		break;
 		break;
@@ -1168,43 +1199,65 @@ static int dvb_init(struct saa7134_dev *dev)
 		}
 		}
 		break;
 		break;
 	case SAA7134_BOARD_CINERGY_HT_PCMCIA:
 	case SAA7134_BOARD_CINERGY_HT_PCMCIA:
-		configure_tda827x_fe(dev, &cinergy_ht_config, &tda827x_cfg_0);
+		if (configure_tda827x_fe(dev, &cinergy_ht_config,
+					 &tda827x_cfg_0) < 0)
+			goto dettach_frontend;
 		break;
 		break;
 	case SAA7134_BOARD_CINERGY_HT_PCI:
 	case SAA7134_BOARD_CINERGY_HT_PCI:
-		configure_tda827x_fe(dev, &cinergy_ht_pci_config, &tda827x_cfg_0);
+		if (configure_tda827x_fe(dev, &cinergy_ht_pci_config,
+					 &tda827x_cfg_0) < 0)
+			goto dettach_frontend;
 		break;
 		break;
 	case SAA7134_BOARD_PHILIPS_TIGER_S:
 	case SAA7134_BOARD_PHILIPS_TIGER_S:
-		configure_tda827x_fe(dev, &philips_tiger_s_config, &tda827x_cfg_2);
+		if (configure_tda827x_fe(dev, &philips_tiger_s_config,
+					 &tda827x_cfg_2) < 0)
+			goto dettach_frontend;
 		break;
 		break;
 	case SAA7134_BOARD_ASUS_P7131_4871:
 	case SAA7134_BOARD_ASUS_P7131_4871:
-		configure_tda827x_fe(dev, &asus_p7131_4871_config, &tda827x_cfg_2);
+		if (configure_tda827x_fe(dev, &asus_p7131_4871_config,
+					 &tda827x_cfg_2) < 0)
+			goto dettach_frontend;
 		break;
 		break;
 	case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
 	case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
-		configure_tda827x_fe(dev, &asus_p7131_hybrid_lna_config, &tda827x_cfg_2);
+		if (configure_tda827x_fe(dev, &asus_p7131_hybrid_lna_config,
+					 &tda827x_cfg_2) < 0)
+			goto dettach_frontend;
 		break;
 		break;
 	case SAA7134_BOARD_AVERMEDIA_SUPER_007:
 	case SAA7134_BOARD_AVERMEDIA_SUPER_007:
-		configure_tda827x_fe(dev, &avermedia_super_007_config, &tda827x_cfg_0);
+		if (configure_tda827x_fe(dev, &avermedia_super_007_config,
+					 &tda827x_cfg_0) < 0)
+			goto dettach_frontend;
 		break;
 		break;
 	case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
 	case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
-		configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config, &tda827x_cfg_2_sw42);
+		if (configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config,
+					 &tda827x_cfg_2_sw42) < 0)
+			goto dettach_frontend;
 		break;
 		break;
 	case SAA7134_BOARD_PHILIPS_SNAKE:
 	case SAA7134_BOARD_PHILIPS_SNAKE:
 		dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
 		dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
 						&dev->i2c_adap);
 						&dev->i2c_adap);
 		if (dev->dvb.frontend) {
 		if (dev->dvb.frontend) {
 			if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
 			if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
-					&dev->i2c_adap, 0) == NULL)
+					&dev->i2c_adap, 0) == NULL) {
 				wprintk("%s: No tda826x found!\n", __func__);
 				wprintk("%s: No tda826x found!\n", __func__);
+				goto dettach_frontend;
+			}
 			if (dvb_attach(lnbp21_attach, dev->dvb.frontend,
 			if (dvb_attach(lnbp21_attach, dev->dvb.frontend,
-					&dev->i2c_adap, 0, 0) == NULL)
+					&dev->i2c_adap, 0, 0) == NULL) {
 				wprintk("%s: No lnbp21 found!\n", __func__);
 				wprintk("%s: No lnbp21 found!\n", __func__);
+				goto dettach_frontend;
+			}
 		}
 		}
 		break;
 		break;
 	case SAA7134_BOARD_CREATIX_CTX953:
 	case SAA7134_BOARD_CREATIX_CTX953:
-		configure_tda827x_fe(dev, &md8800_dvbt_config, &tda827x_cfg_0);
+		if (configure_tda827x_fe(dev, &md8800_dvbt_config,
+					 &tda827x_cfg_0) < 0)
+			goto dettach_frontend;
 		break;
 		break;
 	case SAA7134_BOARD_MSI_TVANYWHERE_AD11:
 	case SAA7134_BOARD_MSI_TVANYWHERE_AD11:
-		configure_tda827x_fe(dev, &philips_tiger_s_config, &tda827x_cfg_2);
+		if (configure_tda827x_fe(dev, &philips_tiger_s_config,
+					 &tda827x_cfg_2) < 0)
+			goto dettach_frontend;
 		break;
 		break;
 	case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
 	case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
 		dev->dvb.frontend = dvb_attach(mt352_attach,
 		dev->dvb.frontend = dvb_attach(mt352_attach,
@@ -1218,16 +1271,20 @@ static int dvb_init(struct saa7134_dev *dev)
 		if (dev->dvb.frontend) {
 		if (dev->dvb.frontend) {
 			struct dvb_frontend *fe;
 			struct dvb_frontend *fe;
 			if (dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
 			if (dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
-				  &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL)
+				  &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) {
 				wprintk("%s: MD7134 DVB-S, no SD1878 "
 				wprintk("%s: MD7134 DVB-S, no SD1878 "
 					"found !\n", __func__);
 					"found !\n", __func__);
+				goto dettach_frontend;
+			}
 			/* we need to open the i2c gate (we know it exists) */
 			/* we need to open the i2c gate (we know it exists) */
 			fe = dev->dvb.frontend;
 			fe = dev->dvb.frontend;
 			fe->ops.i2c_gate_ctrl(fe, 1);
 			fe->ops.i2c_gate_ctrl(fe, 1);
 			if (dvb_attach(isl6405_attach, fe,
 			if (dvb_attach(isl6405_attach, fe,
-					&dev->i2c_adap, 0x08, 0, 0) == NULL)
+					&dev->i2c_adap, 0x08, 0, 0) == NULL) {
 				wprintk("%s: MD7134 DVB-S, no ISL6405 "
 				wprintk("%s: MD7134 DVB-S, no ISL6405 "
 					"found !\n", __func__);
 					"found !\n", __func__);
+				goto dettach_frontend;
+			}
 			fe->ops.i2c_gate_ctrl(fe, 0);
 			fe->ops.i2c_gate_ctrl(fe, 0);
 			dev->original_set_voltage = fe->ops.set_voltage;
 			dev->original_set_voltage = fe->ops.set_voltage;
 			fe->ops.set_voltage = md8800_set_voltage;
 			fe->ops.set_voltage = md8800_set_voltage;
@@ -1254,10 +1311,7 @@ static int dvb_init(struct saa7134_dev *dev)
 		if (!fe) {
 		if (!fe) {
 			printk(KERN_ERR "%s/2: xc3028 attach failed\n",
 			printk(KERN_ERR "%s/2: xc3028 attach failed\n",
 			       dev->name);
 			       dev->name);
-			dvb_frontend_detach(dev->dvb.frontend);
-			dvb_unregister_frontend(dev->dvb.frontend);
-			dev->dvb.frontend = NULL;
-			return -1;
+			goto dettach_frontend;
 		}
 		}
 	}
 	}
 
 
@@ -1282,6 +1336,12 @@ static int dvb_init(struct saa7134_dev *dev)
 			dev->dvb.frontend->ops.tuner_ops.sleep(dev->dvb.frontend);
 			dev->dvb.frontend->ops.tuner_ops.sleep(dev->dvb.frontend);
 	}
 	}
 	return ret;
 	return ret;
+
+dettach_frontend:
+	dvb_frontend_detach(dev->dvb.frontend);
+	dev->dvb.frontend = NULL;
+
+	return -1;
 }
 }
 
 
 static int dvb_fini(struct saa7134_dev *dev)
 static int dvb_fini(struct saa7134_dev *dev)

+ 7 - 0
drivers/media/video/stk-webcam.c

@@ -30,6 +30,7 @@
 #include <linux/kref.h>
 #include <linux/kref.h>
 
 
 #include <linux/usb.h>
 #include <linux/usb.h>
+#include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/vmalloc.h>
 #include <linux/videodev2.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
@@ -245,6 +246,8 @@ static int stk_initialise(struct stk_camera *dev)
 		return -1;
 		return -1;
 }
 }
 
 
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+
 /* sysfs functions */
 /* sysfs functions */
 /*FIXME cleanup this */
 /*FIXME cleanup this */
 
 
@@ -350,6 +353,10 @@ static void stk_remove_sysfs_files(struct video_device *vdev)
 	video_device_remove_file(vdev, &dev_attr_vflip);
 	video_device_remove_file(vdev, &dev_attr_vflip);
 }
 }
 
 
+#else
+#define stk_create_sysfs_files(a)
+#define stk_remove_sysfs_files(a)
+#endif
 
 
 /* *********************************************** */
 /* *********************************************** */
 /*
 /*

+ 18 - 20
drivers/media/video/tuner-core.c

@@ -40,11 +40,11 @@
 	typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
 	typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
 	if (__a) { \
 	if (__a) { \
 		__r = (int) __a(ARGS); \
 		__r = (int) __a(ARGS); \
+		symbol_put(FUNCTION); \
 	} else { \
 	} else { \
 		printk(KERN_ERR "TUNER: Unable to find " \
 		printk(KERN_ERR "TUNER: Unable to find " \
 				"symbol "#FUNCTION"()\n"); \
 				"symbol "#FUNCTION"()\n"); \
 	} \
 	} \
-	symbol_put(FUNCTION); \
 	__r; \
 	__r; \
 })
 })
 
 
@@ -340,16 +340,6 @@ static void tuner_i2c_address_check(struct tuner *t)
 	tuner_warn("====================== WARNING! ======================\n");
 	tuner_warn("====================== WARNING! ======================\n");
 }
 }
 
 
-static void attach_tda829x(struct tuner *t)
-{
-	struct tda829x_config cfg = {
-		.lna_cfg        = t->config,
-		.tuner_callback = t->tuner_callback,
-	};
-	dvb_attach(tda829x_attach,
-		   &t->fe, t->i2c->adapter, t->i2c->addr, &cfg);
-}
-
 static struct xc5000_config xc5000_cfg;
 static struct xc5000_config xc5000_cfg;
 
 
 static void set_type(struct i2c_client *c, unsigned int type,
 static void set_type(struct i2c_client *c, unsigned int type,
@@ -385,12 +375,19 @@ static void set_type(struct i2c_client *c, unsigned int type,
 
 
 	switch (t->type) {
 	switch (t->type) {
 	case TUNER_MT2032:
 	case TUNER_MT2032:
-		dvb_attach(microtune_attach,
-			   &t->fe, t->i2c->adapter, t->i2c->addr);
+		if (!dvb_attach(microtune_attach,
+			   &t->fe, t->i2c->adapter, t->i2c->addr))
+			goto attach_failed;
 		break;
 		break;
 	case TUNER_PHILIPS_TDA8290:
 	case TUNER_PHILIPS_TDA8290:
 	{
 	{
-		attach_tda829x(t);
+		struct tda829x_config cfg = {
+			.lna_cfg        = t->config,
+			.tuner_callback = t->tuner_callback,
+		};
+		if (!dvb_attach(tda829x_attach, &t->fe, t->i2c->adapter,
+				t->i2c->addr, &cfg))
+			goto attach_failed;
 		break;
 		break;
 	}
 	}
 	case TUNER_TEA5767:
 	case TUNER_TEA5767:
@@ -441,8 +438,9 @@ static void set_type(struct i2c_client *c, unsigned int type,
 		break;
 		break;
 	}
 	}
 	case TUNER_TDA9887:
 	case TUNER_TDA9887:
-		dvb_attach(tda9887_attach,
-			   &t->fe, t->i2c->adapter, t->i2c->addr);
+		if (!dvb_attach(tda9887_attach,
+			   &t->fe, t->i2c->adapter, t->i2c->addr))
+			goto attach_failed;
 		break;
 		break;
 	case TUNER_XC5000:
 	case TUNER_XC5000:
 	{
 	{
@@ -450,10 +448,10 @@ static void set_type(struct i2c_client *c, unsigned int type,
 
 
 		xc5000_cfg.i2c_address	  = t->i2c->addr;
 		xc5000_cfg.i2c_address	  = t->i2c->addr;
 		xc5000_cfg.if_khz	  = 5380;
 		xc5000_cfg.if_khz	  = 5380;
-		xc5000_cfg.priv           = c->adapter->algo_data;
 		xc5000_cfg.tuner_callback = t->tuner_callback;
 		xc5000_cfg.tuner_callback = t->tuner_callback;
 		if (!dvb_attach(xc5000_attach,
 		if (!dvb_attach(xc5000_attach,
-				&t->fe, t->i2c->adapter, &xc5000_cfg))
+				&t->fe, t->i2c->adapter, &xc5000_cfg,
+				c->adapter->algo_data))
 			goto attach_failed;
 			goto attach_failed;
 
 
 		xc_tuner_ops = &t->fe.ops.tuner_ops;
 		xc_tuner_ops = &t->fe.ops.tuner_ops;
@@ -1167,7 +1165,7 @@ static int tuner_probe(struct i2c_client *client,
 			/* If chip is not tda8290, don't register.
 			/* If chip is not tda8290, don't register.
 			   since it can be tda9887*/
 			   since it can be tda9887*/
 			if (tuner_symbol_probe(tda829x_probe, t->i2c->adapter,
 			if (tuner_symbol_probe(tda829x_probe, t->i2c->adapter,
-					       t->i2c->addr) == 0) {
+					       t->i2c->addr) >= 0) {
 				tuner_dbg("tda829x detected\n");
 				tuner_dbg("tda829x detected\n");
 			} else {
 			} else {
 				/* Default is being tda9887 */
 				/* Default is being tda9887 */
@@ -1181,7 +1179,7 @@ static int tuner_probe(struct i2c_client *client,
 		case 0x60:
 		case 0x60:
 			if (tuner_symbol_probe(tea5767_autodetection,
 			if (tuner_symbol_probe(tea5767_autodetection,
 					       t->i2c->adapter, t->i2c->addr)
 					       t->i2c->adapter, t->i2c->addr)
-					!= EINVAL) {
+					>= 0) {
 				t->type = TUNER_TEA5767;
 				t->type = TUNER_TEA5767;
 				t->mode_mask = T_RADIO;
 				t->mode_mask = T_RADIO;
 				t->mode = T_STANDBY;
 				t->mode = T_STANDBY;

+ 7 - 3
drivers/media/video/tveeprom.c

@@ -319,10 +319,12 @@ audioIC[] =
 	{AUDIO_CHIP_INTERNAL, "CX25843"},
 	{AUDIO_CHIP_INTERNAL, "CX25843"},
 	{AUDIO_CHIP_INTERNAL, "CX23418"},
 	{AUDIO_CHIP_INTERNAL, "CX23418"},
 	{AUDIO_CHIP_INTERNAL, "CX23885"},
 	{AUDIO_CHIP_INTERNAL, "CX23885"},
-	/* 40-42 */
+	/* 40-44 */
 	{AUDIO_CHIP_INTERNAL, "CX23888"},
 	{AUDIO_CHIP_INTERNAL, "CX23888"},
 	{AUDIO_CHIP_INTERNAL, "SAA7131"},
 	{AUDIO_CHIP_INTERNAL, "SAA7131"},
 	{AUDIO_CHIP_INTERNAL, "CX23887"},
 	{AUDIO_CHIP_INTERNAL, "CX23887"},
+	{AUDIO_CHIP_INTERNAL, "SAA7164"},
+	{AUDIO_CHIP_INTERNAL, "AU8522"},
 };
 };
 
 
 /* This list is supplied by Hauppauge. Thanks! */
 /* This list is supplied by Hauppauge. Thanks! */
@@ -341,8 +343,10 @@ static const char *decoderIC[] = {
 	"CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
 	"CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
 	/* 30-34 */
 	/* 30-34 */
 	"CX25843", "CX23418", "NEC61153", "CX23885", "CX23888",
 	"CX25843", "CX23418", "NEC61153", "CX23885", "CX23888",
-	/* 35-37 */
-	"SAA7131", "CX25837", "CX23887"
+	/* 35-39 */
+	"SAA7131", "CX25837", "CX23887", "CX23885A", "CX23887A",
+	/* 40-42 */
+	"SAA7164", "CX23885B", "AU8522"
 };
 };
 
 
 static int hasRadioTuner(int tunerType)
 static int hasRadioTuner(int tunerType)

+ 1 - 1
drivers/media/video/usbvision/Kconfig

@@ -1,7 +1,7 @@
 config VIDEO_USBVISION
 config VIDEO_USBVISION
 	tristate "USB video devices based on Nogatech NT1003/1004/1005"
 	tristate "USB video devices based on Nogatech NT1003/1004/1005"
 	depends on I2C && VIDEO_V4L2
 	depends on I2C && VIDEO_V4L2
-	select MEDIA_TUNER
+	select VIDEO_TUNER
 	select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
 	select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
 	---help---
 	---help---
 	  There are more than 50 different USB video devices based on
 	  There are more than 50 different USB video devices based on