[media] common: move media/common/tuners to media/tuners
authorMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 14 Jun 2012 19:35:59 +0000 (16:35 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 14 Aug 2012 02:40:28 +0000 (23:40 -0300)
Move the tuners one level up, as the "common" directory will be used
by drivers that are shared between more than one driver.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
171 files changed:
MAINTAINERS
drivers/media/Kconfig
drivers/media/Makefile
drivers/media/common/Makefile
drivers/media/common/b2c2/Makefile
drivers/media/common/tuners/Kconfig [deleted file]
drivers/media/common/tuners/Makefile [deleted file]
drivers/media/common/tuners/fc0011.c [deleted file]
drivers/media/common/tuners/fc0011.h [deleted file]
drivers/media/common/tuners/fc0012-priv.h [deleted file]
drivers/media/common/tuners/fc0012.c [deleted file]
drivers/media/common/tuners/fc0012.h [deleted file]
drivers/media/common/tuners/fc0013-priv.h [deleted file]
drivers/media/common/tuners/fc0013.c [deleted file]
drivers/media/common/tuners/fc0013.h [deleted file]
drivers/media/common/tuners/fc001x-common.h [deleted file]
drivers/media/common/tuners/max2165.c [deleted file]
drivers/media/common/tuners/max2165.h [deleted file]
drivers/media/common/tuners/max2165_priv.h [deleted file]
drivers/media/common/tuners/mc44s803.c [deleted file]
drivers/media/common/tuners/mc44s803.h [deleted file]
drivers/media/common/tuners/mc44s803_priv.h [deleted file]
drivers/media/common/tuners/mt2060.c [deleted file]
drivers/media/common/tuners/mt2060.h [deleted file]
drivers/media/common/tuners/mt2060_priv.h [deleted file]
drivers/media/common/tuners/mt2063.c [deleted file]
drivers/media/common/tuners/mt2063.h [deleted file]
drivers/media/common/tuners/mt20xx.c [deleted file]
drivers/media/common/tuners/mt20xx.h [deleted file]
drivers/media/common/tuners/mt2131.c [deleted file]
drivers/media/common/tuners/mt2131.h [deleted file]
drivers/media/common/tuners/mt2131_priv.h [deleted file]
drivers/media/common/tuners/mt2266.c [deleted file]
drivers/media/common/tuners/mt2266.h [deleted file]
drivers/media/common/tuners/mxl5005s.c [deleted file]
drivers/media/common/tuners/mxl5005s.h [deleted file]
drivers/media/common/tuners/mxl5007t.c [deleted file]
drivers/media/common/tuners/mxl5007t.h [deleted file]
drivers/media/common/tuners/qt1010.c [deleted file]
drivers/media/common/tuners/qt1010.h [deleted file]
drivers/media/common/tuners/qt1010_priv.h [deleted file]
drivers/media/common/tuners/tda18212.c [deleted file]
drivers/media/common/tuners/tda18212.h [deleted file]
drivers/media/common/tuners/tda18218.c [deleted file]
drivers/media/common/tuners/tda18218.h [deleted file]
drivers/media/common/tuners/tda18218_priv.h [deleted file]
drivers/media/common/tuners/tda18271-common.c [deleted file]
drivers/media/common/tuners/tda18271-fe.c [deleted file]
drivers/media/common/tuners/tda18271-maps.c [deleted file]
drivers/media/common/tuners/tda18271-priv.h [deleted file]
drivers/media/common/tuners/tda18271.h [deleted file]
drivers/media/common/tuners/tda827x.c [deleted file]
drivers/media/common/tuners/tda827x.h [deleted file]
drivers/media/common/tuners/tda8290.c [deleted file]
drivers/media/common/tuners/tda8290.h [deleted file]
drivers/media/common/tuners/tda9887.c [deleted file]
drivers/media/common/tuners/tda9887.h [deleted file]
drivers/media/common/tuners/tea5761.c [deleted file]
drivers/media/common/tuners/tea5761.h [deleted file]
drivers/media/common/tuners/tea5767.c [deleted file]
drivers/media/common/tuners/tea5767.h [deleted file]
drivers/media/common/tuners/tua9001.c [deleted file]
drivers/media/common/tuners/tua9001.h [deleted file]
drivers/media/common/tuners/tua9001_priv.h [deleted file]
drivers/media/common/tuners/tuner-i2c.h [deleted file]
drivers/media/common/tuners/tuner-simple.c [deleted file]
drivers/media/common/tuners/tuner-simple.h [deleted file]
drivers/media/common/tuners/tuner-types.c [deleted file]
drivers/media/common/tuners/tuner-xc2028-types.h [deleted file]
drivers/media/common/tuners/tuner-xc2028.c [deleted file]
drivers/media/common/tuners/tuner-xc2028.h [deleted file]
drivers/media/common/tuners/xc4000.c [deleted file]
drivers/media/common/tuners/xc4000.h [deleted file]
drivers/media/common/tuners/xc5000.c [deleted file]
drivers/media/common/tuners/xc5000.h [deleted file]
drivers/media/dvb-frontends/Makefile
drivers/media/pci/bt8xx/Makefile
drivers/media/pci/ddbridge/Makefile
drivers/media/pci/ngene/Makefile
drivers/media/pci/ttpci/Makefile
drivers/media/tuners/Kconfig [new file with mode: 0644]
drivers/media/tuners/Makefile [new file with mode: 0644]
drivers/media/tuners/fc0011.c [new file with mode: 0644]
drivers/media/tuners/fc0011.h [new file with mode: 0644]
drivers/media/tuners/fc0012-priv.h [new file with mode: 0644]
drivers/media/tuners/fc0012.c [new file with mode: 0644]
drivers/media/tuners/fc0012.h [new file with mode: 0644]
drivers/media/tuners/fc0013-priv.h [new file with mode: 0644]
drivers/media/tuners/fc0013.c [new file with mode: 0644]
drivers/media/tuners/fc0013.h [new file with mode: 0644]
drivers/media/tuners/fc001x-common.h [new file with mode: 0644]
drivers/media/tuners/max2165.c [new file with mode: 0644]
drivers/media/tuners/max2165.h [new file with mode: 0644]
drivers/media/tuners/max2165_priv.h [new file with mode: 0644]
drivers/media/tuners/mc44s803.c [new file with mode: 0644]
drivers/media/tuners/mc44s803.h [new file with mode: 0644]
drivers/media/tuners/mc44s803_priv.h [new file with mode: 0644]
drivers/media/tuners/mt2060.c [new file with mode: 0644]
drivers/media/tuners/mt2060.h [new file with mode: 0644]
drivers/media/tuners/mt2060_priv.h [new file with mode: 0644]
drivers/media/tuners/mt2063.c [new file with mode: 0644]
drivers/media/tuners/mt2063.h [new file with mode: 0644]
drivers/media/tuners/mt20xx.c [new file with mode: 0644]
drivers/media/tuners/mt20xx.h [new file with mode: 0644]
drivers/media/tuners/mt2131.c [new file with mode: 0644]
drivers/media/tuners/mt2131.h [new file with mode: 0644]
drivers/media/tuners/mt2131_priv.h [new file with mode: 0644]
drivers/media/tuners/mt2266.c [new file with mode: 0644]
drivers/media/tuners/mt2266.h [new file with mode: 0644]
drivers/media/tuners/mxl5005s.c [new file with mode: 0644]
drivers/media/tuners/mxl5005s.h [new file with mode: 0644]
drivers/media/tuners/mxl5007t.c [new file with mode: 0644]
drivers/media/tuners/mxl5007t.h [new file with mode: 0644]
drivers/media/tuners/qt1010.c [new file with mode: 0644]
drivers/media/tuners/qt1010.h [new file with mode: 0644]
drivers/media/tuners/qt1010_priv.h [new file with mode: 0644]
drivers/media/tuners/tda18212.c [new file with mode: 0644]
drivers/media/tuners/tda18212.h [new file with mode: 0644]
drivers/media/tuners/tda18218.c [new file with mode: 0644]
drivers/media/tuners/tda18218.h [new file with mode: 0644]
drivers/media/tuners/tda18218_priv.h [new file with mode: 0644]
drivers/media/tuners/tda18271-common.c [new file with mode: 0644]
drivers/media/tuners/tda18271-fe.c [new file with mode: 0644]
drivers/media/tuners/tda18271-maps.c [new file with mode: 0644]
drivers/media/tuners/tda18271-priv.h [new file with mode: 0644]
drivers/media/tuners/tda18271.h [new file with mode: 0644]
drivers/media/tuners/tda827x.c [new file with mode: 0644]
drivers/media/tuners/tda827x.h [new file with mode: 0644]
drivers/media/tuners/tda8290.c [new file with mode: 0644]
drivers/media/tuners/tda8290.h [new file with mode: 0644]
drivers/media/tuners/tda9887.c [new file with mode: 0644]
drivers/media/tuners/tda9887.h [new file with mode: 0644]
drivers/media/tuners/tea5761.c [new file with mode: 0644]
drivers/media/tuners/tea5761.h [new file with mode: 0644]
drivers/media/tuners/tea5767.c [new file with mode: 0644]
drivers/media/tuners/tea5767.h [new file with mode: 0644]
drivers/media/tuners/tua9001.c [new file with mode: 0644]
drivers/media/tuners/tua9001.h [new file with mode: 0644]
drivers/media/tuners/tua9001_priv.h [new file with mode: 0644]
drivers/media/tuners/tuner-i2c.h [new file with mode: 0644]
drivers/media/tuners/tuner-simple.c [new file with mode: 0644]
drivers/media/tuners/tuner-simple.h [new file with mode: 0644]
drivers/media/tuners/tuner-types.c [new file with mode: 0644]
drivers/media/tuners/tuner-xc2028-types.h [new file with mode: 0644]
drivers/media/tuners/tuner-xc2028.c [new file with mode: 0644]
drivers/media/tuners/tuner-xc2028.h [new file with mode: 0644]
drivers/media/tuners/xc4000.c [new file with mode: 0644]
drivers/media/tuners/xc4000.h [new file with mode: 0644]
drivers/media/tuners/xc5000.c [new file with mode: 0644]
drivers/media/tuners/xc5000.h [new file with mode: 0644]
drivers/media/usb/b2c2/Makefile
drivers/media/usb/dvb-usb-v2/Makefile
drivers/media/usb/dvb-usb/Makefile
drivers/media/v4l2-core/Makefile
drivers/media/video/Makefile
drivers/media/video/au0828/Makefile
drivers/media/video/bt8xx/Makefile
drivers/media/video/cx18/Makefile
drivers/media/video/cx231xx/Makefile
drivers/media/video/cx23885/Makefile
drivers/media/video/cx25821/Makefile
drivers/media/video/cx88/Makefile
drivers/media/video/em28xx/Makefile
drivers/media/video/ivtv/Makefile
drivers/media/video/pvrusb2/Makefile
drivers/media/video/saa7134/Makefile
drivers/media/video/saa7164/Makefile
drivers/media/video/tlg2300/Makefile
drivers/media/video/tm6000/Makefile
drivers/media/video/usbvision/Makefile
drivers/staging/media/cxd2099/Makefile

index 94b823f71e944d1f8805815c2b16b5bca437d3b7..ceb5b55b2af83b2d0450da21d4151e5adbb8018b 100644 (file)
@@ -2773,8 +2773,8 @@ FC0011 TUNER DRIVER
 M:     Michael Buesch <m@bues.ch>
 L:     linux-media@vger.kernel.org
 S:     Maintained
-F:     drivers/media/common/tuners/fc0011.h
-F:     drivers/media/common/tuners/fc0011.c
+F:     drivers/media/tuners/fc0011.h
+F:     drivers/media/tuners/fc0011.c
 
 FANOTIFY
 M:     Eric Paris <eparis@redhat.com>
index 6343e84b361a9b111a14ca1d6231f89178138cba..aae6fec3b9e1760ffd64d1c46fcea8f6cac1cfbf 100644 (file)
@@ -145,7 +145,7 @@ source "drivers/media/rc/Kconfig"
 # Tuner drivers for DVB and V4L
 #
 
-source "drivers/media/common/tuners/Kconfig"
+source "drivers/media/tuners/Kconfig"
 
 #
 # Video/Radio/Hybrid adapters
index 90ec998a8e6ad1b27729fb1fec105744636ac54c..f89ccace746f150051976a11d3764e0ee776b69d 100644 (file)
@@ -8,7 +8,7 @@ ifeq ($(CONFIG_MEDIA_CONTROLLER),y)
   obj-$(CONFIG_MEDIA_SUPPORT) += media.o
 endif
 
-obj-y += v4l2-core/ common/ rc/ video/
+obj-y += v4l2-core/ tuners/ common/ rc/ video/
 
 obj-$(CONFIG_VIDEO_DEV) += radio/
 obj-$(CONFIG_DVB_CORE)  += dvb-core/ pci/ dvb-frontends/ usb/
index d0512d7e55556a7959d3a70617637d3bc95fa951..a471242c46a72b8703924dbeac62aaa843b93a1f 100644 (file)
@@ -1,6 +1,6 @@
 saa7146-objs    := saa7146_i2c.o saa7146_core.o
 saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
 
-obj-y += tuners/ b2c2/
+obj-y += b2c2/
 obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
 obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o
index 377d051548a9fac3abcf9de07d499341054fef8a..48a4c906a1739be08e3509f296b373229b98502c 100644 (file)
@@ -4,4 +4,4 @@ obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
 
 ccflags-y += -Idrivers/media/dvb-core/
 ccflags-y += -Idrivers/media/dvb-frontends/
-ccflags-y += -Idrivers/media/common/tuners/
+ccflags-y += -Idrivers/media/tuners/
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
deleted file mode 100644 (file)
index 94c6ff7..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-config MEDIA_ATTACH
-       bool "Load and attach frontend and tuner driver modules as needed"
-       depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT
-       depends on MODULES
-       default y if !EXPERT
-       help
-         Remove the static dependency of DVB card drivers on all
-         frontend modules for all possible card variants. Instead,
-         allow the card drivers to only load the frontend modules
-         they require.
-
-         Also, tuner module will automatically load a tuner driver
-         when needed, for analog mode.
-
-         This saves several KBytes of memory.
-
-         Note: You will need module-init-tools v3.2 or later for this feature.
-
-         If unsure say Y.
-
-config MEDIA_TUNER
-       tristate
-       depends on (MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT) && I2C
-       default y
-       select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_XC4000 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMISE && MEDIA_RADIO_SUPPORT && EXPERIMENTAL
-       select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMISE && MEDIA_RADIO_SUPPORT
-       select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMISE
-       select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
-
-config MEDIA_TUNER_CUSTOMISE
-       bool "Customize analog and hybrid tuner modules to build"
-       depends on MEDIA_TUNER
-       default y if EXPERT
-       help
-         This allows the user to deselect tuner drivers unnecessary
-         for their hardware from the build. Use this option with care
-         as deselecting tuner drivers which are in fact necessary will
-         result in V4L/DVB devices which cannot be tuned due to lack of
-         driver support
-
-         If unsure say N.
-
-menu "Customize TV tuners"
-       visible if MEDIA_TUNER_CUSTOMISE
-       depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT
-
-config MEDIA_TUNER_SIMPLE
-       tristate "Simple tuner support"
-       depends on MEDIA_SUPPORT && I2C
-       select MEDIA_TUNER_TDA9887
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to include support for various simple tuners.
-
-config MEDIA_TUNER_TDA8290
-       tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo"
-       depends on MEDIA_SUPPORT && I2C
-       select MEDIA_TUNER_TDA827X
-       select MEDIA_TUNER_TDA18271
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to include support for Philips TDA8290+8275(a) tuner.
-
-config MEDIA_TUNER_TDA827X
-       tristate "Philips TDA827X silicon tuner"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         A DVB-T silicon tuner module. Say Y when you want to support this tuner.
-
-config MEDIA_TUNER_TDA18271
-       tristate "NXP TDA18271 silicon tuner"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         A silicon tuner module. Say Y when you want to support this tuner.
-
-config MEDIA_TUNER_TDA9887
-       tristate "TDA 9885/6/7 analog IF demodulator"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to include support for Philips TDA9885/6/7
-         analog IF demodulator.
-
-config MEDIA_TUNER_TEA5761
-       tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
-       depends on MEDIA_SUPPORT && I2C
-       depends on EXPERIMENTAL
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to include support for the Philips TEA5761 radio tuner.
-
-config MEDIA_TUNER_TEA5767
-       tristate "TEA 5767 radio tuner"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to include support for the Philips TEA5767 radio tuner.
-
-config MEDIA_TUNER_MT20XX
-       tristate "Microtune 2032 / 2050 tuners"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to include support for the MT2032 / MT2050 tuner.
-
-config MEDIA_TUNER_MT2060
-       tristate "Microtune MT2060 silicon IF tuner"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         A driver for the silicon IF tuner MT2060 from Microtune.
-
-config MEDIA_TUNER_MT2063
-       tristate "Microtune MT2063 silicon IF tuner"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         A driver for the silicon IF tuner MT2063 from Microtune.
-
-config MEDIA_TUNER_MT2266
-       tristate "Microtune MT2266 silicon tuner"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         A driver for the silicon baseband tuner MT2266 from Microtune.
-
-config MEDIA_TUNER_MT2131
-       tristate "Microtune MT2131 silicon tuner"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         A driver for the silicon baseband tuner MT2131 from Microtune.
-
-config MEDIA_TUNER_QT1010
-       tristate "Quantek QT1010 silicon tuner"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         A driver for the silicon tuner QT1010 from Quantek.
-
-config MEDIA_TUNER_XC2028
-       tristate "XCeive xc2028/xc3028 tuners"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to include support for the xc2028/xc3028 tuners.
-
-config MEDIA_TUNER_XC5000
-       tristate "Xceive XC5000 silicon tuner"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         A driver for the silicon tuner XC5000 from Xceive.
-         This device is only used inside a SiP called together with a
-         demodulator for now.
-
-config MEDIA_TUNER_XC4000
-       tristate "Xceive XC4000 silicon tuner"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         A driver for the silicon tuner XC4000 from Xceive.
-         This device is only used inside a SiP called together with a
-         demodulator for now.
-
-config MEDIA_TUNER_MXL5005S
-       tristate "MaxLinear MSL5005S silicon tuner"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         A driver for the silicon tuner MXL5005S from MaxLinear.
-
-config MEDIA_TUNER_MXL5007T
-       tristate "MaxLinear MxL5007T silicon tuner"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         A driver for the silicon tuner MxL5007T from MaxLinear.
-
-config MEDIA_TUNER_MC44S803
-       tristate "Freescale MC44S803 Low Power CMOS Broadband tuners"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         Say Y here to support the Freescale MC44S803 based tuners
-
-config MEDIA_TUNER_MAX2165
-       tristate "Maxim MAX2165 silicon tuner"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         A driver for the silicon tuner MAX2165 from Maxim.
-
-config MEDIA_TUNER_TDA18218
-       tristate "NXP TDA18218 silicon tuner"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         NXP TDA18218 silicon tuner driver.
-
-config MEDIA_TUNER_FC0011
-       tristate "Fitipower FC0011 silicon tuner"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         Fitipower FC0011 silicon tuner driver.
-
-config MEDIA_TUNER_FC0012
-       tristate "Fitipower FC0012 silicon tuner"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         Fitipower FC0012 silicon tuner driver.
-
-config MEDIA_TUNER_FC0013
-       tristate "Fitipower FC0013 silicon tuner"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         Fitipower FC0013 silicon tuner driver.
-
-config MEDIA_TUNER_TDA18212
-       tristate "NXP TDA18212 silicon tuner"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         NXP TDA18212 silicon tuner driver.
-
-config MEDIA_TUNER_TUA9001
-       tristate "Infineon TUA 9001 silicon tuner"
-       depends on MEDIA_SUPPORT && I2C
-       default m if MEDIA_TUNER_CUSTOMISE
-       help
-         Infineon TUA 9001 silicon tuner driver.
-endmenu
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
deleted file mode 100644 (file)
index 112aeee..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# Makefile for common V4L/DVB tuners
-#
-
-tda18271-objs := tda18271-maps.o tda18271-common.o tda18271-fe.o
-
-obj-$(CONFIG_MEDIA_TUNER_XC2028) += tuner-xc2028.o
-obj-$(CONFIG_MEDIA_TUNER_SIMPLE) += tuner-simple.o
-# tuner-types will be merged into tuner-simple, in the future
-obj-$(CONFIG_MEDIA_TUNER_SIMPLE) += tuner-types.o
-obj-$(CONFIG_MEDIA_TUNER_MT20XX) += mt20xx.o
-obj-$(CONFIG_MEDIA_TUNER_TDA8290) += tda8290.o
-obj-$(CONFIG_MEDIA_TUNER_TEA5767) += tea5767.o
-obj-$(CONFIG_MEDIA_TUNER_TEA5761) += tea5761.o
-obj-$(CONFIG_MEDIA_TUNER_TDA9887) += tda9887.o
-obj-$(CONFIG_MEDIA_TUNER_TDA827X) += tda827x.o
-obj-$(CONFIG_MEDIA_TUNER_TDA18271) += tda18271.o
-obj-$(CONFIG_MEDIA_TUNER_XC5000) += xc5000.o
-obj-$(CONFIG_MEDIA_TUNER_XC4000) += xc4000.o
-obj-$(CONFIG_MEDIA_TUNER_MT2060) += mt2060.o
-obj-$(CONFIG_MEDIA_TUNER_MT2063) += mt2063.o
-obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o
-obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
-obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
-obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
-obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
-obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
-obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
-obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o
-obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o
-obj-$(CONFIG_MEDIA_TUNER_TUA9001) += tua9001.o
-obj-$(CONFIG_MEDIA_TUNER_FC0011) += fc0011.o
-obj-$(CONFIG_MEDIA_TUNER_FC0012) += fc0012.o
-obj-$(CONFIG_MEDIA_TUNER_FC0013) += fc0013.o
-
-ccflags-y += -I$(srctree)/drivers/media/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
diff --git a/drivers/media/common/tuners/fc0011.c b/drivers/media/common/tuners/fc0011.c
deleted file mode 100644 (file)
index e488254..0000000
+++ /dev/null
@@ -1,524 +0,0 @@
-/*
- * Fitipower FC0011 tuner driver
- *
- * Copyright (C) 2012 Michael Buesch <m@bues.ch>
- *
- * Derived from FC0012 tuner driver:
- * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
- *
- * 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.
- */
-
-#include "fc0011.h"
-
-
-/* Tuner registers */
-enum {
-       FC11_REG_0,
-       FC11_REG_FA,            /* FA */
-       FC11_REG_FP,            /* FP */
-       FC11_REG_XINHI,         /* XIN high 8 bit */
-       FC11_REG_XINLO,         /* XIN low 8 bit */
-       FC11_REG_VCO,           /* VCO */
-       FC11_REG_VCOSEL,        /* VCO select */
-       FC11_REG_7,             /* Unknown tuner reg 7 */
-       FC11_REG_8,             /* Unknown tuner reg 8 */
-       FC11_REG_9,
-       FC11_REG_10,            /* Unknown tuner reg 10 */
-       FC11_REG_11,            /* Unknown tuner reg 11 */
-       FC11_REG_12,
-       FC11_REG_RCCAL,         /* RC calibrate */
-       FC11_REG_VCOCAL,        /* VCO calibrate */
-       FC11_REG_15,
-       FC11_REG_16,            /* Unknown tuner reg 16 */
-       FC11_REG_17,
-
-       FC11_NR_REGS,           /* Number of registers */
-};
-
-enum FC11_REG_VCOSEL_bits {
-       FC11_VCOSEL_2           = 0x08, /* VCO select 2 */
-       FC11_VCOSEL_1           = 0x10, /* VCO select 1 */
-       FC11_VCOSEL_CLKOUT      = 0x20, /* Fix clock out */
-       FC11_VCOSEL_BW7M        = 0x40, /* 7MHz bw */
-       FC11_VCOSEL_BW6M        = 0x80, /* 6MHz bw */
-};
-
-enum FC11_REG_RCCAL_bits {
-       FC11_RCCAL_FORCE        = 0x10, /* force */
-};
-
-enum FC11_REG_VCOCAL_bits {
-       FC11_VCOCAL_RUN         = 0,    /* VCO calibration run */
-       FC11_VCOCAL_VALUEMASK   = 0x3F, /* VCO calibration value mask */
-       FC11_VCOCAL_OK          = 0x40, /* VCO calibration Ok */
-       FC11_VCOCAL_RESET       = 0x80, /* VCO calibration reset */
-};
-
-
-struct fc0011_priv {
-       struct i2c_adapter *i2c;
-       u8 addr;
-
-       u32 frequency;
-       u32 bandwidth;
-};
-
-
-static int fc0011_writereg(struct fc0011_priv *priv, u8 reg, u8 val)
-{
-       u8 buf[2] = { reg, val };
-       struct i2c_msg msg = { .addr = priv->addr,
-               .flags = 0, .buf = buf, .len = 2 };
-
-       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
-               dev_err(&priv->i2c->dev,
-                       "I2C write reg failed, reg: %02x, val: %02x\n",
-                       reg, val);
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static int fc0011_readreg(struct fc0011_priv *priv, u8 reg, u8 *val)
-{
-       u8 dummy;
-       struct i2c_msg msg[2] = {
-               { .addr = priv->addr,
-                 .flags = 0, .buf = &reg, .len = 1 },
-               { .addr = priv->addr,
-                 .flags = I2C_M_RD, .buf = val ? : &dummy, .len = 1 },
-       };
-
-       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
-               dev_err(&priv->i2c->dev,
-                       "I2C read failed, reg: %02x\n", reg);
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static int fc0011_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-
-       return 0;
-}
-
-static int fc0011_init(struct dvb_frontend *fe)
-{
-       struct fc0011_priv *priv = fe->tuner_priv;
-       int err;
-
-       if (WARN_ON(!fe->callback))
-               return -EINVAL;
-
-       err = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
-                          FC0011_FE_CALLBACK_POWER, priv->addr);
-       if (err) {
-               dev_err(&priv->i2c->dev, "Power-on callback failed\n");
-               return err;
-       }
-       err = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
-                          FC0011_FE_CALLBACK_RESET, priv->addr);
-       if (err) {
-               dev_err(&priv->i2c->dev, "Reset callback failed\n");
-               return err;
-       }
-
-       return 0;
-}
-
-/* Initiate VCO calibration */
-static int fc0011_vcocal_trigger(struct fc0011_priv *priv)
-{
-       int err;
-
-       err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RESET);
-       if (err)
-               return err;
-       err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RUN);
-       if (err)
-               return err;
-
-       return 0;
-}
-
-/* Read VCO calibration value */
-static int fc0011_vcocal_read(struct fc0011_priv *priv, u8 *value)
-{
-       int err;
-
-       err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RUN);
-       if (err)
-               return err;
-       usleep_range(10000, 20000);
-       err = fc0011_readreg(priv, FC11_REG_VCOCAL, value);
-       if (err)
-               return err;
-
-       return 0;
-}
-
-static int fc0011_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       struct fc0011_priv *priv = fe->tuner_priv;
-       int err;
-       unsigned int i, vco_retries;
-       u32 freq = p->frequency / 1000;
-       u32 bandwidth = p->bandwidth_hz / 1000;
-       u32 fvco, xin, xdiv, xdivr;
-       u16 frac;
-       u8 fa, fp, vco_sel, vco_cal;
-       u8 regs[FC11_NR_REGS] = { };
-
-       regs[FC11_REG_7] = 0x0F;
-       regs[FC11_REG_8] = 0x3E;
-       regs[FC11_REG_10] = 0xB8;
-       regs[FC11_REG_11] = 0x80;
-       regs[FC11_REG_RCCAL] = 0x04;
-       err = fc0011_writereg(priv, FC11_REG_7, regs[FC11_REG_7]);
-       err |= fc0011_writereg(priv, FC11_REG_8, regs[FC11_REG_8]);
-       err |= fc0011_writereg(priv, FC11_REG_10, regs[FC11_REG_10]);
-       err |= fc0011_writereg(priv, FC11_REG_11, regs[FC11_REG_11]);
-       err |= fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
-       if (err)
-               return -EIO;
-
-       /* Set VCO freq and VCO div */
-       if (freq < 54000) {
-               fvco = freq * 64;
-               regs[FC11_REG_VCO] = 0x82;
-       } else if (freq < 108000) {
-               fvco = freq * 32;
-               regs[FC11_REG_VCO] = 0x42;
-       } else if (freq < 216000) {
-               fvco = freq * 16;
-               regs[FC11_REG_VCO] = 0x22;
-       } else if (freq < 432000) {
-               fvco = freq * 8;
-               regs[FC11_REG_VCO] = 0x12;
-       } else {
-               fvco = freq * 4;
-               regs[FC11_REG_VCO] = 0x0A;
-       }
-
-       /* Calc XIN. The PLL reference frequency is 18 MHz. */
-       xdiv = fvco / 18000;
-       frac = fvco - xdiv * 18000;
-       frac = (frac << 15) / 18000;
-       if (frac >= 16384)
-               frac += 32786;
-       if (!frac)
-               xin = 0;
-       else if (frac < 511)
-               xin = 512;
-       else if (frac < 65026)
-               xin = frac;
-       else
-               xin = 65024;
-       regs[FC11_REG_XINHI] = xin >> 8;
-       regs[FC11_REG_XINLO] = xin;
-
-       /* Calc FP and FA */
-       xdivr = xdiv;
-       if (fvco - xdiv * 18000 >= 9000)
-               xdivr += 1; /* round */
-       fp = xdivr / 8;
-       fa = xdivr - fp * 8;
-       if (fa < 2) {
-               fp -= 1;
-               fa += 8;
-       }
-       if (fp > 0x1F) {
-               fp &= 0x1F;
-               fa &= 0xF;
-       }
-       if (fa >= fp) {
-               dev_warn(&priv->i2c->dev,
-                        "fa %02X >= fp %02X, but trying to continue\n",
-                        (unsigned int)(u8)fa, (unsigned int)(u8)fp);
-       }
-       regs[FC11_REG_FA] = fa;
-       regs[FC11_REG_FP] = fp;
-
-       /* Select bandwidth */
-       switch (bandwidth) {
-       case 8000:
-               break;
-       case 7000:
-               regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_BW7M;
-               break;
-       default:
-               dev_warn(&priv->i2c->dev, "Unsupported bandwidth %u kHz. "
-                        "Using 6000 kHz.\n",
-                        bandwidth);
-               bandwidth = 6000;
-               /* fallthrough */
-       case 6000:
-               regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_BW6M;
-               break;
-       }
-
-       /* Pre VCO select */
-       if (fvco < 2320000) {
-               vco_sel = 0;
-               regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
-       } else if (fvco < 3080000) {
-               vco_sel = 1;
-               regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
-               regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
-       } else {
-               vco_sel = 2;
-               regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
-               regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
-       }
-
-       /* Fix for low freqs */
-       if (freq < 45000) {
-               regs[FC11_REG_FA] = 0x6;
-               regs[FC11_REG_FP] = 0x11;
-       }
-
-       /* Clock out fix */
-       regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_CLKOUT;
-
-       /* Write the cached registers */
-       for (i = FC11_REG_FA; i <= FC11_REG_VCOSEL; i++) {
-               err = fc0011_writereg(priv, i, regs[i]);
-               if (err)
-                       return err;
-       }
-
-       /* VCO calibration */
-       err = fc0011_vcocal_trigger(priv);
-       if (err)
-               return err;
-       err = fc0011_vcocal_read(priv, &vco_cal);
-       if (err)
-               return err;
-       vco_retries = 0;
-       while (!(vco_cal & FC11_VCOCAL_OK) && vco_retries < 3) {
-               /* Reset the tuner and try again */
-               err = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
-                                  FC0011_FE_CALLBACK_RESET, priv->addr);
-               if (err) {
-                       dev_err(&priv->i2c->dev, "Failed to reset tuner\n");
-                       return err;
-               }
-               /* Reinit tuner config */
-               err = 0;
-               for (i = FC11_REG_FA; i <= FC11_REG_VCOSEL; i++)
-                       err |= fc0011_writereg(priv, i, regs[i]);
-               err |= fc0011_writereg(priv, FC11_REG_7, regs[FC11_REG_7]);
-               err |= fc0011_writereg(priv, FC11_REG_8, regs[FC11_REG_8]);
-               err |= fc0011_writereg(priv, FC11_REG_10, regs[FC11_REG_10]);
-               err |= fc0011_writereg(priv, FC11_REG_11, regs[FC11_REG_11]);
-               err |= fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
-               if (err)
-                       return -EIO;
-               /* VCO calibration */
-               err = fc0011_vcocal_trigger(priv);
-               if (err)
-                       return err;
-               err = fc0011_vcocal_read(priv, &vco_cal);
-               if (err)
-                       return err;
-               vco_retries++;
-       }
-       if (!(vco_cal & FC11_VCOCAL_OK)) {
-               dev_err(&priv->i2c->dev,
-                       "Failed to read VCO calibration value (got %02X)\n",
-                       (unsigned int)vco_cal);
-               return -EIO;
-       }
-       vco_cal &= FC11_VCOCAL_VALUEMASK;
-
-       switch (vco_sel) {
-       case 0:
-               if (vco_cal < 8) {
-                       regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
-                       regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
-                       err = fc0011_writereg(priv, FC11_REG_VCOSEL,
-                                             regs[FC11_REG_VCOSEL]);
-                       if (err)
-                               return err;
-                       err = fc0011_vcocal_trigger(priv);
-                       if (err)
-                               return err;
-               } else {
-                       regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
-                       err = fc0011_writereg(priv, FC11_REG_VCOSEL,
-                                             regs[FC11_REG_VCOSEL]);
-                       if (err)
-                               return err;
-               }
-               break;
-       case 1:
-               if (vco_cal < 5) {
-                       regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
-                       regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
-                       err = fc0011_writereg(priv, FC11_REG_VCOSEL,
-                                             regs[FC11_REG_VCOSEL]);
-                       if (err)
-                               return err;
-                       err = fc0011_vcocal_trigger(priv);
-                       if (err)
-                               return err;
-               } else if (vco_cal <= 48) {
-                       regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
-                       regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
-                       err = fc0011_writereg(priv, FC11_REG_VCOSEL,
-                                             regs[FC11_REG_VCOSEL]);
-                       if (err)
-                               return err;
-               } else {
-                       regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
-                       err = fc0011_writereg(priv, FC11_REG_VCOSEL,
-                                             regs[FC11_REG_VCOSEL]);
-                       if (err)
-                               return err;
-                       err = fc0011_vcocal_trigger(priv);
-                       if (err)
-                               return err;
-               }
-               break;
-       case 2:
-               if (vco_cal > 53) {
-                       regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
-                       regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
-                       err = fc0011_writereg(priv, FC11_REG_VCOSEL,
-                                             regs[FC11_REG_VCOSEL]);
-                       if (err)
-                               return err;
-                       err = fc0011_vcocal_trigger(priv);
-                       if (err)
-                               return err;
-               } else {
-                       regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
-                       regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
-                       err = fc0011_writereg(priv, FC11_REG_VCOSEL,
-                                             regs[FC11_REG_VCOSEL]);
-                       if (err)
-                               return err;
-               }
-               break;
-       }
-       err = fc0011_vcocal_read(priv, NULL);
-       if (err)
-               return err;
-       usleep_range(10000, 50000);
-
-       err = fc0011_readreg(priv, FC11_REG_RCCAL, &regs[FC11_REG_RCCAL]);
-       if (err)
-               return err;
-       regs[FC11_REG_RCCAL] |= FC11_RCCAL_FORCE;
-       err = fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
-       if (err)
-               return err;
-       err = fc0011_writereg(priv, FC11_REG_16, 0xB);
-       if (err)
-               return err;
-
-       dev_dbg(&priv->i2c->dev, "Tuned to "
-               "fa=%02X fp=%02X xin=%02X%02X vco=%02X vcosel=%02X "
-               "vcocal=%02X(%u) bw=%u\n",
-               (unsigned int)regs[FC11_REG_FA],
-               (unsigned int)regs[FC11_REG_FP],
-               (unsigned int)regs[FC11_REG_XINHI],
-               (unsigned int)regs[FC11_REG_XINLO],
-               (unsigned int)regs[FC11_REG_VCO],
-               (unsigned int)regs[FC11_REG_VCOSEL],
-               (unsigned int)vco_cal, vco_retries,
-               (unsigned int)bandwidth);
-
-       priv->frequency = p->frequency;
-       priv->bandwidth = p->bandwidth_hz;
-
-       return 0;
-}
-
-static int fc0011_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct fc0011_priv *priv = fe->tuner_priv;
-
-       *frequency = priv->frequency;
-
-       return 0;
-}
-
-static int fc0011_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       *frequency = 0;
-
-       return 0;
-}
-
-static int fc0011_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct fc0011_priv *priv = fe->tuner_priv;
-
-       *bandwidth = priv->bandwidth;
-
-       return 0;
-}
-
-static const struct dvb_tuner_ops fc0011_tuner_ops = {
-       .info = {
-               .name           = "Fitipower FC0011",
-
-               .frequency_min  = 45000000,
-               .frequency_max  = 1000000000,
-       },
-
-       .release                = fc0011_release,
-       .init                   = fc0011_init,
-
-       .set_params             = fc0011_set_params,
-
-       .get_frequency          = fc0011_get_frequency,
-       .get_if_frequency       = fc0011_get_if_frequency,
-       .get_bandwidth          = fc0011_get_bandwidth,
-};
-
-struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe,
-                                  struct i2c_adapter *i2c,
-                                  const struct fc0011_config *config)
-{
-       struct fc0011_priv *priv;
-
-       priv = kzalloc(sizeof(struct fc0011_priv), GFP_KERNEL);
-       if (!priv)
-               return NULL;
-
-       priv->i2c = i2c;
-       priv->addr = config->i2c_address;
-
-       fe->tuner_priv = priv;
-       fe->ops.tuner_ops = fc0011_tuner_ops;
-
-       dev_info(&priv->i2c->dev, "Fitipower FC0011 tuner attached\n");
-
-       return fe;
-}
-EXPORT_SYMBOL(fc0011_attach);
-
-MODULE_DESCRIPTION("Fitipower FC0011 silicon tuner driver");
-MODULE_AUTHOR("Michael Buesch <m@bues.ch>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/fc0011.h b/drivers/media/common/tuners/fc0011.h
deleted file mode 100644 (file)
index 0ee581f..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef LINUX_FC0011_H_
-#define LINUX_FC0011_H_
-
-#include "dvb_frontend.h"
-
-
-/** struct fc0011_config - fc0011 hardware config
- *
- * @i2c_address: I2C bus address.
- */
-struct fc0011_config {
-       u8 i2c_address;
-};
-
-/** enum fc0011_fe_callback_commands - Frontend callbacks
- *
- * @FC0011_FE_CALLBACK_POWER: Power on tuner hardware.
- * @FC0011_FE_CALLBACK_RESET: Request a tuner reset.
- */
-enum fc0011_fe_callback_commands {
-       FC0011_FE_CALLBACK_POWER,
-       FC0011_FE_CALLBACK_RESET,
-};
-
-#if defined(CONFIG_MEDIA_TUNER_FC0011) ||\
-    defined(CONFIG_MEDIA_TUNER_FC0011_MODULE)
-struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe,
-                                  struct i2c_adapter *i2c,
-                                  const struct fc0011_config *config);
-#else
-static inline
-struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe,
-                                  struct i2c_adapter *i2c,
-                                  const struct fc0011_config *config)
-{
-       dev_err(&i2c->dev, "fc0011 driver disabled in Kconfig\n");
-       return NULL;
-}
-#endif
-
-#endif /* LINUX_FC0011_H_ */
diff --git a/drivers/media/common/tuners/fc0012-priv.h b/drivers/media/common/tuners/fc0012-priv.h
deleted file mode 100644 (file)
index 4577c91..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Fitipower FC0012 tuner driver - private includes
- *
- * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
- *
- * 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 _FC0012_PRIV_H_
-#define _FC0012_PRIV_H_
-
-#define LOG_PREFIX "fc0012"
-
-#undef err
-#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
-#undef info
-#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
-#undef warn
-#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
-
-struct fc0012_priv {
-       struct i2c_adapter *i2c;
-       u8 addr;
-       u8 dual_master;
-       u8 xtal_freq;
-
-       u32 frequency;
-       u32 bandwidth;
-};
-
-#endif
diff --git a/drivers/media/common/tuners/fc0012.c b/drivers/media/common/tuners/fc0012.c
deleted file mode 100644 (file)
index 308135a..0000000
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * Fitipower FC0012 tuner driver
- *
- * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
- *
- * 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.
- */
-
-#include "fc0012.h"
-#include "fc0012-priv.h"
-
-static int fc0012_writereg(struct fc0012_priv *priv, u8 reg, u8 val)
-{
-       u8 buf[2] = {reg, val};
-       struct i2c_msg msg = {
-               .addr = priv->addr, .flags = 0, .buf = buf, .len = 2
-       };
-
-       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
-               err("I2C write reg failed, reg: %02x, val: %02x", reg, val);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int fc0012_readreg(struct fc0012_priv *priv, u8 reg, u8 *val)
-{
-       struct i2c_msg msg[2] = {
-               { .addr = priv->addr, .flags = 0, .buf = &reg, .len = 1 },
-               { .addr = priv->addr, .flags = I2C_M_RD, .buf = val, .len = 1 },
-       };
-
-       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
-               err("I2C read reg failed, reg: %02x", reg);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int fc0012_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static int fc0012_init(struct dvb_frontend *fe)
-{
-       struct fc0012_priv *priv = fe->tuner_priv;
-       int i, ret = 0;
-       unsigned char reg[] = {
-               0x00,   /* dummy reg. 0 */
-               0x05,   /* reg. 0x01 */
-               0x10,   /* reg. 0x02 */
-               0x00,   /* reg. 0x03 */
-               0x00,   /* reg. 0x04 */
-               0x0f,   /* reg. 0x05: may also be 0x0a */
-               0x00,   /* reg. 0x06: divider 2, VCO slow */
-               0x00,   /* reg. 0x07: may also be 0x0f */
-               0xff,   /* reg. 0x08: AGC Clock divide by 256, AGC gain 1/256,
-                          Loop Bw 1/8 */
-               0x6e,   /* reg. 0x09: Disable LoopThrough, Enable LoopThrough: 0x6f */
-               0xb8,   /* reg. 0x0a: Disable LO Test Buffer */
-               0x82,   /* reg. 0x0b: Output Clock is same as clock frequency,
-                          may also be 0x83 */
-               0xfc,   /* reg. 0x0c: depending on AGC Up-Down mode, may need 0xf8 */
-               0x02,   /* reg. 0x0d: AGC Not Forcing & LNA Forcing, 0x02 for DVB-T */
-               0x00,   /* reg. 0x0e */
-               0x00,   /* reg. 0x0f */
-               0x00,   /* reg. 0x10: may also be 0x0d */
-               0x00,   /* reg. 0x11 */
-               0x1f,   /* reg. 0x12: Set to maximum gain */
-               0x08,   /* reg. 0x13: Set to Middle Gain: 0x08,
-                          Low Gain: 0x00, High Gain: 0x10, enable IX2: 0x80 */
-               0x00,   /* reg. 0x14 */
-               0x04,   /* reg. 0x15: Enable LNA COMPS */
-       };
-
-       switch (priv->xtal_freq) {
-       case FC_XTAL_27_MHZ:
-       case FC_XTAL_28_8_MHZ:
-               reg[0x07] |= 0x20;
-               break;
-       case FC_XTAL_36_MHZ:
-       default:
-               break;
-       }
-
-       if (priv->dual_master)
-               reg[0x0c] |= 0x02;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
-
-       for (i = 1; i < sizeof(reg); i++) {
-               ret = fc0012_writereg(priv, i, reg[i]);
-               if (ret)
-                       break;
-       }
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
-
-       if (ret)
-               err("fc0012_writereg failed: %d", ret);
-
-       return ret;
-}
-
-static int fc0012_sleep(struct dvb_frontend *fe)
-{
-       /* nothing to do here */
-       return 0;
-}
-
-static int fc0012_set_params(struct dvb_frontend *fe)
-{
-       struct fc0012_priv *priv = fe->tuner_priv;
-       int i, ret = 0;
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       u32 freq = p->frequency / 1000;
-       u32 delsys = p->delivery_system;
-       unsigned char reg[7], am, pm, multi, tmp;
-       unsigned long f_vco;
-       unsigned short xtal_freq_khz_2, xin, xdiv;
-       int vco_select = false;
-
-       if (fe->callback) {
-               ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
-                       FC_FE_CALLBACK_VHF_ENABLE, (freq > 300000 ? 0 : 1));
-               if (ret)
-                       goto exit;
-       }
-
-       switch (priv->xtal_freq) {
-       case FC_XTAL_27_MHZ:
-               xtal_freq_khz_2 = 27000 / 2;
-               break;
-       case FC_XTAL_36_MHZ:
-               xtal_freq_khz_2 = 36000 / 2;
-               break;
-       case FC_XTAL_28_8_MHZ:
-       default:
-               xtal_freq_khz_2 = 28800 / 2;
-               break;
-       }
-
-       /* select frequency divider and the frequency of VCO */
-       if (freq < 37084) {             /* freq * 96 < 3560000 */
-               multi = 96;
-               reg[5] = 0x82;
-               reg[6] = 0x00;
-       } else if (freq < 55625) {      /* freq * 64 < 3560000 */
-               multi = 64;
-               reg[5] = 0x82;
-               reg[6] = 0x02;
-       } else if (freq < 74167) {      /* freq * 48 < 3560000 */
-               multi = 48;
-               reg[5] = 0x42;
-               reg[6] = 0x00;
-       } else if (freq < 111250) {     /* freq * 32 < 3560000 */
-               multi = 32;
-               reg[5] = 0x42;
-               reg[6] = 0x02;
-       } else if (freq < 148334) {     /* freq * 24 < 3560000 */
-               multi = 24;
-               reg[5] = 0x22;
-               reg[6] = 0x00;
-       } else if (freq < 222500) {     /* freq * 16 < 3560000 */
-               multi = 16;
-               reg[5] = 0x22;
-               reg[6] = 0x02;
-       } else if (freq < 296667) {     /* freq * 12 < 3560000 */
-               multi = 12;
-               reg[5] = 0x12;
-               reg[6] = 0x00;
-       } else if (freq < 445000) {     /* freq * 8 < 3560000 */
-               multi = 8;
-               reg[5] = 0x12;
-               reg[6] = 0x02;
-       } else if (freq < 593334) {     /* freq * 6 < 3560000 */
-               multi = 6;
-               reg[5] = 0x0a;
-               reg[6] = 0x00;
-       } else {
-               multi = 4;
-               reg[5] = 0x0a;
-               reg[6] = 0x02;
-       }
-
-       f_vco = freq * multi;
-
-       if (f_vco >= 3060000) {
-               reg[6] |= 0x08;
-               vco_select = true;
-       }
-
-       if (freq >= 45000) {
-               /* From divided value (XDIV) determined the FA and FP value */
-               xdiv = (unsigned short)(f_vco / xtal_freq_khz_2);
-               if ((f_vco - xdiv * xtal_freq_khz_2) >= (xtal_freq_khz_2 / 2))
-                       xdiv++;
-
-               pm = (unsigned char)(xdiv / 8);
-               am = (unsigned char)(xdiv - (8 * pm));
-
-               if (am < 2) {
-                       reg[1] = am + 8;
-                       reg[2] = pm - 1;
-               } else {
-                       reg[1] = am;
-                       reg[2] = pm;
-               }
-       } else {
-               /* fix for frequency less than 45 MHz */
-               reg[1] = 0x06;
-               reg[2] = 0x11;
-       }
-
-       /* fix clock out */
-       reg[6] |= 0x20;
-
-       /* From VCO frequency determines the XIN ( fractional part of Delta
-          Sigma PLL) and divided value (XDIV) */
-       xin = (unsigned short)(f_vco - (f_vco / xtal_freq_khz_2) * xtal_freq_khz_2);
-       xin = (xin << 15) / xtal_freq_khz_2;
-       if (xin >= 16384)
-               xin += 32768;
-
-       reg[3] = xin >> 8;      /* xin with 9 bit resolution */
-       reg[4] = xin & 0xff;
-
-       if (delsys == SYS_DVBT) {
-               reg[6] &= 0x3f; /* bits 6 and 7 describe the bandwidth */
-               switch (p->bandwidth_hz) {
-               case 6000000:
-                       reg[6] |= 0x80;
-                       break;
-               case 7000000:
-                       reg[6] |= 0x40;
-                       break;
-               case 8000000:
-               default:
-                       break;
-               }
-       } else {
-               err("%s: modulation type not supported!", __func__);
-               return -EINVAL;
-       }
-
-       /* modified for Realtek demod */
-       reg[5] |= 0x07;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
-
-       for (i = 1; i <= 6; i++) {
-               ret = fc0012_writereg(priv, i, reg[i]);
-               if (ret)
-                       goto exit;
-       }
-
-       /* VCO Calibration */
-       ret = fc0012_writereg(priv, 0x0e, 0x80);
-       if (!ret)
-               ret = fc0012_writereg(priv, 0x0e, 0x00);
-
-       /* VCO Re-Calibration if needed */
-       if (!ret)
-               ret = fc0012_writereg(priv, 0x0e, 0x00);
-
-       if (!ret) {
-               msleep(10);
-               ret = fc0012_readreg(priv, 0x0e, &tmp);
-       }
-       if (ret)
-               goto exit;
-
-       /* vco selection */
-       tmp &= 0x3f;
-
-       if (vco_select) {
-               if (tmp > 0x3c) {
-                       reg[6] &= ~0x08;
-                       ret = fc0012_writereg(priv, 0x06, reg[6]);
-                       if (!ret)
-                               ret = fc0012_writereg(priv, 0x0e, 0x80);
-                       if (!ret)
-                               ret = fc0012_writereg(priv, 0x0e, 0x00);
-               }
-       } else {
-               if (tmp < 0x02) {
-                       reg[6] |= 0x08;
-                       ret = fc0012_writereg(priv, 0x06, reg[6]);
-                       if (!ret)
-                               ret = fc0012_writereg(priv, 0x0e, 0x80);
-                       if (!ret)
-                               ret = fc0012_writereg(priv, 0x0e, 0x00);
-               }
-       }
-
-       priv->frequency = p->frequency;
-       priv->bandwidth = p->bandwidth_hz;
-
-exit:
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
-       if (ret)
-               warn("%s: failed: %d", __func__, ret);
-       return ret;
-}
-
-static int fc0012_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct fc0012_priv *priv = fe->tuner_priv;
-       *frequency = priv->frequency;
-       return 0;
-}
-
-static int fc0012_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       /* CHECK: always ? */
-       *frequency = 0;
-       return 0;
-}
-
-static int fc0012_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct fc0012_priv *priv = fe->tuner_priv;
-       *bandwidth = priv->bandwidth;
-       return 0;
-}
-
-#define INPUT_ADC_LEVEL        -8
-
-static int fc0012_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct fc0012_priv *priv = fe->tuner_priv;
-       int ret;
-       unsigned char tmp;
-       int int_temp, lna_gain, int_lna, tot_agc_gain, power;
-       const int fc0012_lna_gain_table[] = {
-               /* low gain */
-               -63, -58, -99, -73,
-               -63, -65, -54, -60,
-               /* middle gain */
-                71,  70,  68,  67,
-                65,  63,  61,  58,
-               /* high gain */
-               197, 191, 188, 186,
-               184, 182, 181, 179,
-       };
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
-
-       ret = fc0012_writereg(priv, 0x12, 0x00);
-       if (ret)
-               goto err;
-
-       ret = fc0012_readreg(priv, 0x12, &tmp);
-       if (ret)
-               goto err;
-       int_temp = tmp;
-
-       ret = fc0012_readreg(priv, 0x13, &tmp);
-       if (ret)
-               goto err;
-       lna_gain = tmp & 0x1f;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
-
-       if (lna_gain < ARRAY_SIZE(fc0012_lna_gain_table)) {
-               int_lna = fc0012_lna_gain_table[lna_gain];
-               tot_agc_gain = (abs((int_temp >> 5) - 7) - 2 +
-                               (int_temp & 0x1f)) * 2;
-               power = INPUT_ADC_LEVEL - tot_agc_gain - int_lna / 10;
-
-               if (power >= 45)
-                       *strength = 255;        /* 100% */
-               else if (power < -95)
-                       *strength = 0;
-               else
-                       *strength = (power + 95) * 255 / 140;
-
-               *strength |= *strength << 8;
-       } else {
-               ret = -1;
-       }
-
-       goto exit;
-
-err:
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
-exit:
-       if (ret)
-               warn("%s: failed: %d", __func__, ret);
-       return ret;
-}
-
-static const struct dvb_tuner_ops fc0012_tuner_ops = {
-       .info = {
-               .name           = "Fitipower FC0012",
-
-               .frequency_min  = 37000000,     /* estimate */
-               .frequency_max  = 862000000,    /* estimate */
-               .frequency_step = 0,
-       },
-
-       .release        = fc0012_release,
-
-       .init           = fc0012_init,
-       .sleep          = fc0012_sleep,
-
-       .set_params     = fc0012_set_params,
-
-       .get_frequency  = fc0012_get_frequency,
-       .get_if_frequency = fc0012_get_if_frequency,
-       .get_bandwidth  = fc0012_get_bandwidth,
-
-       .get_rf_strength = fc0012_get_rf_strength,
-};
-
-struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe,
-       struct i2c_adapter *i2c, u8 i2c_address, int dual_master,
-       enum fc001x_xtal_freq xtal_freq)
-{
-       struct fc0012_priv *priv = NULL;
-
-       priv = kzalloc(sizeof(struct fc0012_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->i2c = i2c;
-       priv->dual_master = dual_master;
-       priv->addr = i2c_address;
-       priv->xtal_freq = xtal_freq;
-
-       info("Fitipower FC0012 successfully attached.");
-
-       fe->tuner_priv = priv;
-
-       memcpy(&fe->ops.tuner_ops, &fc0012_tuner_ops,
-               sizeof(struct dvb_tuner_ops));
-
-       return fe;
-}
-EXPORT_SYMBOL(fc0012_attach);
-
-MODULE_DESCRIPTION("Fitipower FC0012 silicon tuner driver");
-MODULE_AUTHOR("Hans-Frieder Vogt <hfvogt@gmx.net>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.6");
diff --git a/drivers/media/common/tuners/fc0012.h b/drivers/media/common/tuners/fc0012.h
deleted file mode 100644 (file)
index 4dbd5ef..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Fitipower FC0012 tuner driver - include
- *
- * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
- *
- * 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 _FC0012_H_
-#define _FC0012_H_
-
-#include "dvb_frontend.h"
-#include "fc001x-common.h"
-
-#if defined(CONFIG_MEDIA_TUNER_FC0012) || \
-       (defined(CONFIG_MEDIA_TUNER_FC0012_MODULE) && defined(MODULE))
-extern struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe,
-                                       struct i2c_adapter *i2c,
-                                       u8 i2c_address, int dual_master,
-                                       enum fc001x_xtal_freq xtal_freq);
-#else
-static inline struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe,
-                                       struct i2c_adapter *i2c,
-                                       u8 i2c_address, int dual_master,
-                                       enum fc001x_xtal_freq xtal_freq)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif
diff --git a/drivers/media/common/tuners/fc0013-priv.h b/drivers/media/common/tuners/fc0013-priv.h
deleted file mode 100644 (file)
index bfd49de..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Fitipower FC0013 tuner driver
- *
- * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
- *
- *    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 _FC0013_PRIV_H_
-#define _FC0013_PRIV_H_
-
-#define LOG_PREFIX "fc0013"
-
-#undef err
-#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
-#undef info
-#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
-#undef warn
-#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
-
-struct fc0013_priv {
-       struct i2c_adapter *i2c;
-       u8 addr;
-       u8 dual_master;
-       u8 xtal_freq;
-
-       u32 frequency;
-       u32 bandwidth;
-};
-
-#endif
diff --git a/drivers/media/common/tuners/fc0013.c b/drivers/media/common/tuners/fc0013.c
deleted file mode 100644 (file)
index bd8f0f1..0000000
+++ /dev/null
@@ -1,634 +0,0 @@
-/*
- * Fitipower FC0013 tuner driver
- *
- * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
- * partially based on driver code from Fitipower
- * Copyright (C) 2010 Fitipower Integrated Technology Inc
- *
- *    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.
- *
- */
-
-#include "fc0013.h"
-#include "fc0013-priv.h"
-
-static int fc0013_writereg(struct fc0013_priv *priv, u8 reg, u8 val)
-{
-       u8 buf[2] = {reg, val};
-       struct i2c_msg msg = {
-               .addr = priv->addr, .flags = 0, .buf = buf, .len = 2
-       };
-
-       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
-               err("I2C write reg failed, reg: %02x, val: %02x", reg, val);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int fc0013_readreg(struct fc0013_priv *priv, u8 reg, u8 *val)
-{
-       struct i2c_msg msg[2] = {
-               { .addr = priv->addr, .flags = 0, .buf = &reg, .len = 1 },
-               { .addr = priv->addr, .flags = I2C_M_RD, .buf = val, .len = 1 },
-       };
-
-       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
-               err("I2C read reg failed, reg: %02x", reg);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int fc0013_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static int fc0013_init(struct dvb_frontend *fe)
-{
-       struct fc0013_priv *priv = fe->tuner_priv;
-       int i, ret = 0;
-       unsigned char reg[] = {
-               0x00,   /* reg. 0x00: dummy */
-               0x09,   /* reg. 0x01 */
-               0x16,   /* reg. 0x02 */
-               0x00,   /* reg. 0x03 */
-               0x00,   /* reg. 0x04 */
-               0x17,   /* reg. 0x05 */
-               0x02,   /* reg. 0x06 */
-               0x0a,   /* reg. 0x07: CHECK */
-               0xff,   /* reg. 0x08: AGC Clock divide by 256, AGC gain 1/256,
-                          Loop Bw 1/8 */
-               0x6f,   /* reg. 0x09: enable LoopThrough */
-               0xb8,   /* reg. 0x0a: Disable LO Test Buffer */
-               0x82,   /* reg. 0x0b: CHECK */
-               0xfc,   /* reg. 0x0c: depending on AGC Up-Down mode, may need 0xf8 */
-               0x01,   /* reg. 0x0d: AGC Not Forcing & LNA Forcing, may need 0x02 */
-               0x00,   /* reg. 0x0e */
-               0x00,   /* reg. 0x0f */
-               0x00,   /* reg. 0x10 */
-               0x00,   /* reg. 0x11 */
-               0x00,   /* reg. 0x12 */
-               0x00,   /* reg. 0x13 */
-               0x50,   /* reg. 0x14: DVB-t High Gain, UHF.
-                          Middle Gain: 0x48, Low Gain: 0x40 */
-               0x01,   /* reg. 0x15 */
-       };
-
-       switch (priv->xtal_freq) {
-       case FC_XTAL_27_MHZ:
-       case FC_XTAL_28_8_MHZ:
-               reg[0x07] |= 0x20;
-               break;
-       case FC_XTAL_36_MHZ:
-       default:
-               break;
-       }
-
-       if (priv->dual_master)
-               reg[0x0c] |= 0x02;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
-
-       for (i = 1; i < sizeof(reg); i++) {
-               ret = fc0013_writereg(priv, i, reg[i]);
-               if (ret)
-                       break;
-       }
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
-
-       if (ret)
-               err("fc0013_writereg failed: %d", ret);
-
-       return ret;
-}
-
-static int fc0013_sleep(struct dvb_frontend *fe)
-{
-       /* nothing to do here */
-       return 0;
-}
-
-int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val)
-{
-       struct fc0013_priv *priv = fe->tuner_priv;
-       int ret;
-       u8 rc_cal;
-       int val;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
-
-       /* push rc_cal value, get rc_cal value */
-       ret = fc0013_writereg(priv, 0x10, 0x00);
-       if (ret)
-               goto error_out;
-
-       /* get rc_cal value */
-       ret = fc0013_readreg(priv, 0x10, &rc_cal);
-       if (ret)
-               goto error_out;
-
-       rc_cal &= 0x0f;
-
-       val = (int)rc_cal + rc_val;
-
-       /* forcing rc_cal */
-       ret = fc0013_writereg(priv, 0x0d, 0x11);
-       if (ret)
-               goto error_out;
-
-       /* modify rc_cal value */
-       if (val > 15)
-               ret = fc0013_writereg(priv, 0x10, 0x0f);
-       else if (val < 0)
-               ret = fc0013_writereg(priv, 0x10, 0x00);
-       else
-               ret = fc0013_writereg(priv, 0x10, (u8)val);
-
-error_out:
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
-
-       return ret;
-}
-EXPORT_SYMBOL(fc0013_rc_cal_add);
-
-int fc0013_rc_cal_reset(struct dvb_frontend *fe)
-{
-       struct fc0013_priv *priv = fe->tuner_priv;
-       int ret;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
-
-       ret = fc0013_writereg(priv, 0x0d, 0x01);
-       if (!ret)
-               ret = fc0013_writereg(priv, 0x10, 0x00);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
-
-       return ret;
-}
-EXPORT_SYMBOL(fc0013_rc_cal_reset);
-
-static int fc0013_set_vhf_track(struct fc0013_priv *priv, u32 freq)
-{
-       int ret;
-       u8 tmp;
-
-       ret = fc0013_readreg(priv, 0x1d, &tmp);
-       if (ret)
-               goto error_out;
-       tmp &= 0xe3;
-       if (freq <= 177500) {           /* VHF Track: 7 */
-               ret = fc0013_writereg(priv, 0x1d, tmp | 0x1c);
-       } else if (freq <= 184500) {    /* VHF Track: 6 */
-               ret = fc0013_writereg(priv, 0x1d, tmp | 0x18);
-       } else if (freq <= 191500) {    /* VHF Track: 5 */
-               ret = fc0013_writereg(priv, 0x1d, tmp | 0x14);
-       } else if (freq <= 198500) {    /* VHF Track: 4 */
-               ret = fc0013_writereg(priv, 0x1d, tmp | 0x10);
-       } else if (freq <= 205500) {    /* VHF Track: 3 */
-               ret = fc0013_writereg(priv, 0x1d, tmp | 0x0c);
-       } else if (freq <= 219500) {    /* VHF Track: 2 */
-               ret = fc0013_writereg(priv, 0x1d, tmp | 0x08);
-       } else if (freq < 300000) {     /* VHF Track: 1 */
-               ret = fc0013_writereg(priv, 0x1d, tmp | 0x04);
-       } else {                        /* UHF and GPS */
-               ret = fc0013_writereg(priv, 0x1d, tmp | 0x1c);
-       }
-       if (ret)
-               goto error_out;
-error_out:
-       return ret;
-}
-
-static int fc0013_set_params(struct dvb_frontend *fe)
-{
-       struct fc0013_priv *priv = fe->tuner_priv;
-       int i, ret = 0;
-       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
-       u32 freq = p->frequency / 1000;
-       u32 delsys = p->delivery_system;
-       unsigned char reg[7], am, pm, multi, tmp;
-       unsigned long f_vco;
-       unsigned short xtal_freq_khz_2, xin, xdiv;
-       int vco_select = false;
-
-       if (fe->callback) {
-               ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
-                       FC_FE_CALLBACK_VHF_ENABLE, (freq > 300000 ? 0 : 1));
-               if (ret)
-                       goto exit;
-       }
-
-       switch (priv->xtal_freq) {
-       case FC_XTAL_27_MHZ:
-               xtal_freq_khz_2 = 27000 / 2;
-               break;
-       case FC_XTAL_36_MHZ:
-               xtal_freq_khz_2 = 36000 / 2;
-               break;
-       case FC_XTAL_28_8_MHZ:
-       default:
-               xtal_freq_khz_2 = 28800 / 2;
-               break;
-       }
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
-
-       /* set VHF track */
-       ret = fc0013_set_vhf_track(priv, freq);
-       if (ret)
-               goto exit;
-
-       if (freq < 300000) {
-               /* enable VHF filter */
-               ret = fc0013_readreg(priv, 0x07, &tmp);
-               if (ret)
-                       goto exit;
-               ret = fc0013_writereg(priv, 0x07, tmp | 0x10);
-               if (ret)
-                       goto exit;
-
-               /* disable UHF & disable GPS */
-               ret = fc0013_readreg(priv, 0x14, &tmp);
-               if (ret)
-                       goto exit;
-               ret = fc0013_writereg(priv, 0x14, tmp & 0x1f);
-               if (ret)
-                       goto exit;
-       } else if (freq <= 862000) {
-               /* disable VHF filter */
-               ret = fc0013_readreg(priv, 0x07, &tmp);
-               if (ret)
-                       goto exit;
-               ret = fc0013_writereg(priv, 0x07, tmp & 0xef);
-               if (ret)
-                       goto exit;
-
-               /* enable UHF & disable GPS */
-               ret = fc0013_readreg(priv, 0x14, &tmp);
-               if (ret)
-                       goto exit;
-               ret = fc0013_writereg(priv, 0x14, (tmp & 0x1f) | 0x40);
-               if (ret)
-                       goto exit;
-       } else {
-               /* disable VHF filter */
-               ret = fc0013_readreg(priv, 0x07, &tmp);
-               if (ret)
-                       goto exit;
-               ret = fc0013_writereg(priv, 0x07, tmp & 0xef);
-               if (ret)
-                       goto exit;
-
-               /* disable UHF & enable GPS */
-               ret = fc0013_readreg(priv, 0x14, &tmp);
-               if (ret)
-                       goto exit;
-               ret = fc0013_writereg(priv, 0x14, (tmp & 0x1f) | 0x20);
-               if (ret)
-                       goto exit;
-       }
-
-       /* select frequency divider and the frequency of VCO */
-       if (freq < 37084) {             /* freq * 96 < 3560000 */
-               multi = 96;
-               reg[5] = 0x82;
-               reg[6] = 0x00;
-       } else if (freq < 55625) {      /* freq * 64 < 3560000 */
-               multi = 64;
-               reg[5] = 0x02;
-               reg[6] = 0x02;
-       } else if (freq < 74167) {      /* freq * 48 < 3560000 */
-               multi = 48;
-               reg[5] = 0x42;
-               reg[6] = 0x00;
-       } else if (freq < 111250) {     /* freq * 32 < 3560000 */
-               multi = 32;
-               reg[5] = 0x82;
-               reg[6] = 0x02;
-       } else if (freq < 148334) {     /* freq * 24 < 3560000 */
-               multi = 24;
-               reg[5] = 0x22;
-               reg[6] = 0x00;
-       } else if (freq < 222500) {     /* freq * 16 < 3560000 */
-               multi = 16;
-               reg[5] = 0x42;
-               reg[6] = 0x02;
-       } else if (freq < 296667) {     /* freq * 12 < 3560000 */
-               multi = 12;
-               reg[5] = 0x12;
-               reg[6] = 0x00;
-       } else if (freq < 445000) {     /* freq * 8 < 3560000 */
-               multi = 8;
-               reg[5] = 0x22;
-               reg[6] = 0x02;
-       } else if (freq < 593334) {     /* freq * 6 < 3560000 */
-               multi = 6;
-               reg[5] = 0x0a;
-               reg[6] = 0x00;
-       } else if (freq < 950000) {     /* freq * 4 < 3800000 */
-               multi = 4;
-               reg[5] = 0x12;
-               reg[6] = 0x02;
-       } else {
-               multi = 2;
-               reg[5] = 0x0a;
-               reg[6] = 0x02;
-       }
-
-       f_vco = freq * multi;
-
-       if (f_vco >= 3060000) {
-               reg[6] |= 0x08;
-               vco_select = true;
-       }
-
-       if (freq >= 45000) {
-               /* From divided value (XDIV) determined the FA and FP value */
-               xdiv = (unsigned short)(f_vco / xtal_freq_khz_2);
-               if ((f_vco - xdiv * xtal_freq_khz_2) >= (xtal_freq_khz_2 / 2))
-                       xdiv++;
-
-               pm = (unsigned char)(xdiv / 8);
-               am = (unsigned char)(xdiv - (8 * pm));
-
-               if (am < 2) {
-                       reg[1] = am + 8;
-                       reg[2] = pm - 1;
-               } else {
-                       reg[1] = am;
-                       reg[2] = pm;
-               }
-       } else {
-               /* fix for frequency less than 45 MHz */
-               reg[1] = 0x06;
-               reg[2] = 0x11;
-       }
-
-       /* fix clock out */
-       reg[6] |= 0x20;
-
-       /* From VCO frequency determines the XIN ( fractional part of Delta
-          Sigma PLL) and divided value (XDIV) */
-       xin = (unsigned short)(f_vco - (f_vco / xtal_freq_khz_2) * xtal_freq_khz_2);
-       xin = (xin << 15) / xtal_freq_khz_2;
-       if (xin >= 16384)
-               xin += 32768;
-
-       reg[3] = xin >> 8;
-       reg[4] = xin & 0xff;
-
-       if (delsys == SYS_DVBT) {
-               reg[6] &= 0x3f; /* bits 6 and 7 describe the bandwidth */
-               switch (p->bandwidth_hz) {
-               case 6000000:
-                       reg[6] |= 0x80;
-                       break;
-               case 7000000:
-                       reg[6] |= 0x40;
-                       break;
-               case 8000000:
-               default:
-                       break;
-               }
-       } else {
-               err("%s: modulation type not supported!", __func__);
-               return -EINVAL;
-       }
-
-       /* modified for Realtek demod */
-       reg[5] |= 0x07;
-
-       for (i = 1; i <= 6; i++) {
-               ret = fc0013_writereg(priv, i, reg[i]);
-               if (ret)
-                       goto exit;
-       }
-
-       ret = fc0013_readreg(priv, 0x11, &tmp);
-       if (ret)
-               goto exit;
-       if (multi == 64)
-               ret = fc0013_writereg(priv, 0x11, tmp | 0x04);
-       else
-               ret = fc0013_writereg(priv, 0x11, tmp & 0xfb);
-       if (ret)
-               goto exit;
-
-       /* VCO Calibration */
-       ret = fc0013_writereg(priv, 0x0e, 0x80);
-       if (!ret)
-               ret = fc0013_writereg(priv, 0x0e, 0x00);
-
-       /* VCO Re-Calibration if needed */
-       if (!ret)
-               ret = fc0013_writereg(priv, 0x0e, 0x00);
-
-       if (!ret) {
-               msleep(10);
-               ret = fc0013_readreg(priv, 0x0e, &tmp);
-       }
-       if (ret)
-               goto exit;
-
-       /* vco selection */
-       tmp &= 0x3f;
-
-       if (vco_select) {
-               if (tmp > 0x3c) {
-                       reg[6] &= ~0x08;
-                       ret = fc0013_writereg(priv, 0x06, reg[6]);
-                       if (!ret)
-                               ret = fc0013_writereg(priv, 0x0e, 0x80);
-                       if (!ret)
-                               ret = fc0013_writereg(priv, 0x0e, 0x00);
-               }
-       } else {
-               if (tmp < 0x02) {
-                       reg[6] |= 0x08;
-                       ret = fc0013_writereg(priv, 0x06, reg[6]);
-                       if (!ret)
-                               ret = fc0013_writereg(priv, 0x0e, 0x80);
-                       if (!ret)
-                               ret = fc0013_writereg(priv, 0x0e, 0x00);
-               }
-       }
-
-       priv->frequency = p->frequency;
-       priv->bandwidth = p->bandwidth_hz;
-
-exit:
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
-       if (ret)
-               warn("%s: failed: %d", __func__, ret);
-       return ret;
-}
-
-static int fc0013_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct fc0013_priv *priv = fe->tuner_priv;
-       *frequency = priv->frequency;
-       return 0;
-}
-
-static int fc0013_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       /* always ? */
-       *frequency = 0;
-       return 0;
-}
-
-static int fc0013_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct fc0013_priv *priv = fe->tuner_priv;
-       *bandwidth = priv->bandwidth;
-       return 0;
-}
-
-#define INPUT_ADC_LEVEL        -8
-
-static int fc0013_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct fc0013_priv *priv = fe->tuner_priv;
-       int ret;
-       unsigned char tmp;
-       int int_temp, lna_gain, int_lna, tot_agc_gain, power;
-       const int fc0013_lna_gain_table[] = {
-               /* low gain */
-               -63, -58, -99, -73,
-               -63, -65, -54, -60,
-               /* middle gain */
-                71,  70,  68,  67,
-                65,  63,  61,  58,
-               /* high gain */
-               197, 191, 188, 186,
-               184, 182, 181, 179,
-       };
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
-
-       ret = fc0013_writereg(priv, 0x13, 0x00);
-       if (ret)
-               goto err;
-
-       ret = fc0013_readreg(priv, 0x13, &tmp);
-       if (ret)
-               goto err;
-       int_temp = tmp;
-
-       ret = fc0013_readreg(priv, 0x14, &tmp);
-       if (ret)
-               goto err;
-       lna_gain = tmp & 0x1f;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
-
-       if (lna_gain < ARRAY_SIZE(fc0013_lna_gain_table)) {
-               int_lna = fc0013_lna_gain_table[lna_gain];
-               tot_agc_gain = (abs((int_temp >> 5) - 7) - 2 +
-                               (int_temp & 0x1f)) * 2;
-               power = INPUT_ADC_LEVEL - tot_agc_gain - int_lna / 10;
-
-               if (power >= 45)
-                       *strength = 255;        /* 100% */
-               else if (power < -95)
-                       *strength = 0;
-               else
-                       *strength = (power + 95) * 255 / 140;
-
-               *strength |= *strength << 8;
-       } else {
-               ret = -1;
-       }
-
-       goto exit;
-
-err:
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
-exit:
-       if (ret)
-               warn("%s: failed: %d", __func__, ret);
-       return ret;
-}
-
-static const struct dvb_tuner_ops fc0013_tuner_ops = {
-       .info = {
-               .name           = "Fitipower FC0013",
-
-               .frequency_min  = 37000000,     /* estimate */
-               .frequency_max  = 1680000000,   /* CHECK */
-               .frequency_step = 0,
-       },
-
-       .release        = fc0013_release,
-
-       .init           = fc0013_init,
-       .sleep          = fc0013_sleep,
-
-       .set_params     = fc0013_set_params,
-
-       .get_frequency  = fc0013_get_frequency,
-       .get_if_frequency = fc0013_get_if_frequency,
-       .get_bandwidth  = fc0013_get_bandwidth,
-
-       .get_rf_strength = fc0013_get_rf_strength,
-};
-
-struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe,
-       struct i2c_adapter *i2c, u8 i2c_address, int dual_master,
-       enum fc001x_xtal_freq xtal_freq)
-{
-       struct fc0013_priv *priv = NULL;
-
-       priv = kzalloc(sizeof(struct fc0013_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->i2c = i2c;
-       priv->dual_master = dual_master;
-       priv->addr = i2c_address;
-       priv->xtal_freq = xtal_freq;
-
-       info("Fitipower FC0013 successfully attached.");
-
-       fe->tuner_priv = priv;
-
-       memcpy(&fe->ops.tuner_ops, &fc0013_tuner_ops,
-               sizeof(struct dvb_tuner_ops));
-
-       return fe;
-}
-EXPORT_SYMBOL(fc0013_attach);
-
-MODULE_DESCRIPTION("Fitipower FC0013 silicon tuner driver");
-MODULE_AUTHOR("Hans-Frieder Vogt <hfvogt@gmx.net>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.2");
diff --git a/drivers/media/common/tuners/fc0013.h b/drivers/media/common/tuners/fc0013.h
deleted file mode 100644 (file)
index 594efd6..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Fitipower FC0013 tuner driver
- *
- * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
- *
- *    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 _FC0013_H_
-#define _FC0013_H_
-
-#include "dvb_frontend.h"
-#include "fc001x-common.h"
-
-#if defined(CONFIG_MEDIA_TUNER_FC0013) || \
-       (defined(CONFIG_MEDIA_TUNER_FC0013_MODULE) && defined(MODULE))
-extern struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe,
-                                       struct i2c_adapter *i2c,
-                                       u8 i2c_address, int dual_master,
-                                       enum fc001x_xtal_freq xtal_freq);
-extern int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val);
-extern int fc0013_rc_cal_reset(struct dvb_frontend *fe);
-#else
-static inline struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe,
-                                       struct i2c_adapter *i2c,
-                                       u8 i2c_address, int dual_master,
-                                       enum fc001x_xtal_freq xtal_freq)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-static inline int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val)
-{
-       return 0;
-}
-
-static inline int fc0013_rc_cal_reset(struct dvb_frontend *fe)
-{
-       return 0;
-}
-#endif
-
-#endif
diff --git a/drivers/media/common/tuners/fc001x-common.h b/drivers/media/common/tuners/fc001x-common.h
deleted file mode 100644 (file)
index 7188181..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Fitipower FC0012 & FC0013 tuner driver - common defines
- *
- * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
- *
- * 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 _FC001X_COMMON_H_
-#define _FC001X_COMMON_H_
-
-enum fc001x_xtal_freq {
-       FC_XTAL_27_MHZ,         /* 27000000 */
-       FC_XTAL_28_8_MHZ,       /* 28800000 */
-       FC_XTAL_36_MHZ,         /* 36000000 */
-};
-
-/*
- * enum fc001x_fe_callback_commands - Frontend callbacks
- *
- * @FC_FE_CALLBACK_VHF_ENABLE: enable VHF or UHF
- */
-enum fc001x_fe_callback_commands {
-       FC_FE_CALLBACK_VHF_ENABLE,
-};
-
-#endif
diff --git a/drivers/media/common/tuners/max2165.c b/drivers/media/common/tuners/max2165.c
deleted file mode 100644 (file)
index ba84936..0000000
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- *  Driver for Maxim MAX2165 silicon tuner
- *
- *  Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/videodev2.h>
-#include <linux/delay.h>
-#include <linux/dvb/frontend.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-
-#include "max2165.h"
-#include "max2165_priv.h"
-#include "tuner-i2c.h"
-
-#define dprintk(args...) \
-       do { \
-               if (debug) \
-                       printk(KERN_DEBUG "max2165: " args); \
-       } while (0)
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-static int max2165_write_reg(struct max2165_priv *priv, u8 reg, u8 data)
-{
-       int ret;
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
-
-       msg.addr = priv->config->i2c_address;
-
-       if (debug >= 2)
-               dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, data);
-
-       ret = i2c_transfer(priv->i2c, &msg, 1);
-
-       if (ret != 1)
-               dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
-                       __func__, reg, data, ret);
-
-       return (ret != 1) ? -EIO : 0;
-}
-
-static int max2165_read_reg(struct max2165_priv *priv, u8 reg, u8 *p_data)
-{
-       int ret;
-       u8 dev_addr = priv->config->i2c_address;
-
-       u8 b0[] = { reg };
-       u8 b1[] = { 0 };
-       struct i2c_msg msg[] = {
-               { .addr = dev_addr, .flags = 0, .buf = b0, .len = 1 },
-               { .addr = dev_addr, .flags = I2C_M_RD, .buf = b1, .len = 1 },
-       };
-
-       ret = i2c_transfer(priv->i2c, msg, 2);
-       if (ret != 2) {
-               dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret);
-               return -EIO;
-       }
-
-       *p_data = b1[0];
-       if (debug >= 2)
-               dprintk("%s: reg=0x%02X, data=0x%02X\n",
-                       __func__, reg, b1[0]);
-       return 0;
-}
-
-static int max2165_mask_write_reg(struct max2165_priv *priv, u8 reg,
-       u8 mask, u8 data)
-{
-       int ret;
-       u8 v;
-
-       data &= mask;
-       ret = max2165_read_reg(priv, reg, &v);
-       if (ret != 0)
-               return ret;
-       v &= ~mask;
-       v |= data;
-       ret = max2165_write_reg(priv, reg, v);
-
-       return ret;
-}
-
-static int max2165_read_rom_table(struct max2165_priv *priv)
-{
-       u8 dat[3];
-       int i;
-
-       for (i = 0; i < 3; i++) {
-               max2165_write_reg(priv, REG_ROM_TABLE_ADDR, i + 1);
-               max2165_read_reg(priv, REG_ROM_TABLE_DATA, &dat[i]);
-       }
-
-       priv->tf_ntch_low_cfg = dat[0] >> 4;
-       priv->tf_ntch_hi_cfg = dat[0] & 0x0F;
-       priv->tf_balun_low_ref = dat[1] & 0x0F;
-       priv->tf_balun_hi_ref = dat[1] >> 4;
-       priv->bb_filter_7mhz_cfg = dat[2] & 0x0F;
-       priv->bb_filter_8mhz_cfg = dat[2] >> 4;
-
-       dprintk("tf_ntch_low_cfg = 0x%X\n", priv->tf_ntch_low_cfg);
-       dprintk("tf_ntch_hi_cfg = 0x%X\n", priv->tf_ntch_hi_cfg);
-       dprintk("tf_balun_low_ref = 0x%X\n", priv->tf_balun_low_ref);
-       dprintk("tf_balun_hi_ref = 0x%X\n", priv->tf_balun_hi_ref);
-       dprintk("bb_filter_7mhz_cfg = 0x%X\n", priv->bb_filter_7mhz_cfg);
-       dprintk("bb_filter_8mhz_cfg = 0x%X\n", priv->bb_filter_8mhz_cfg);
-
-       return 0;
-}
-
-static int max2165_set_osc(struct max2165_priv *priv, u8 osc /*MHz*/)
-{
-       u8 v;
-
-       v = (osc / 2);
-       if (v == 2)
-               v = 0x7;
-       else
-               v -= 8;
-
-       max2165_mask_write_reg(priv, REG_PLL_CFG, 0x07, v);
-
-       return 0;
-}
-
-static int max2165_set_bandwidth(struct max2165_priv *priv, u32 bw)
-{
-       u8 val;
-
-       if (bw == 8000000)
-               val = priv->bb_filter_8mhz_cfg;
-       else
-               val = priv->bb_filter_7mhz_cfg;
-
-       max2165_mask_write_reg(priv, REG_BASEBAND_CTRL, 0xF0, val << 4);
-
-       return 0;
-}
-
-int fixpt_div32(u32 dividend, u32 divisor, u32 *quotient, u32 *fraction)
-{
-       u32 remainder;
-       u32 q, f = 0;
-       int i;
-
-       if (0 == divisor)
-               return -EINVAL;
-
-       q = dividend / divisor;
-       remainder = dividend - q * divisor;
-
-       for (i = 0; i < 31; i++) {
-               remainder <<= 1;
-               if (remainder >= divisor) {
-                       f += 1;
-                       remainder -= divisor;
-               }
-               f <<= 1;
-       }
-
-       *quotient = q;
-       *fraction = f;
-
-       return 0;
-}
-
-static int max2165_set_rf(struct max2165_priv *priv, u32 freq)
-{
-       u8 tf;
-       u8 tf_ntch;
-       u32 t;
-       u32 quotient, fraction;
-       int ret;
-
-       /* Set PLL divider according to RF frequency */
-       ret = fixpt_div32(freq / 1000, priv->config->osc_clk * 1000,
-                        &quotient, &fraction);
-       if (ret != 0)
-               return ret;
-
-       /* 20-bit fraction */
-       fraction >>= 12;
-
-       max2165_write_reg(priv, REG_NDIV_INT, quotient);
-       max2165_mask_write_reg(priv, REG_NDIV_FRAC2, 0x0F, fraction >> 16);
-       max2165_write_reg(priv, REG_NDIV_FRAC1, fraction >> 8);
-       max2165_write_reg(priv, REG_NDIV_FRAC0, fraction);
-
-       /* Norch Filter */
-       tf_ntch = (freq < 725000000) ?
-               priv->tf_ntch_low_cfg : priv->tf_ntch_hi_cfg;
-
-       /* Tracking filter balun */
-       t = priv->tf_balun_low_ref;
-       t += (priv->tf_balun_hi_ref - priv->tf_balun_low_ref)
-               * (freq / 1000 - 470000) / (780000 - 470000);
-
-       tf = t;
-       dprintk("tf = %X\n", tf);
-       tf |= tf_ntch << 4;
-
-       max2165_write_reg(priv, REG_TRACK_FILTER, tf);
-
-       return 0;
-}
-
-static void max2165_debug_status(struct max2165_priv *priv)
-{
-       u8 status, autotune;
-       u8 auto_vco_success, auto_vco_active;
-       u8 pll_locked;
-       u8 dc_offset_low, dc_offset_hi;
-       u8 signal_lv_over_threshold;
-       u8 vco, vco_sub_band, adc;
-
-       max2165_read_reg(priv, REG_STATUS, &status);
-       max2165_read_reg(priv, REG_AUTOTUNE, &autotune);
-
-       auto_vco_success = (status >> 6) & 0x01;
-       auto_vco_active = (status >> 5) & 0x01;
-       pll_locked = (status >> 4) & 0x01;
-       dc_offset_low = (status >> 3) & 0x01;
-       dc_offset_hi = (status >> 2) & 0x01;
-       signal_lv_over_threshold = status & 0x01;
-
-       vco = autotune >> 6;
-       vco_sub_band = (autotune >> 3) & 0x7;
-       adc = autotune & 0x7;
-
-       dprintk("auto VCO active: %d, auto VCO success: %d\n",
-               auto_vco_active, auto_vco_success);
-       dprintk("PLL locked: %d\n", pll_locked);
-       dprintk("DC offset low: %d, DC offset high: %d\n",
-               dc_offset_low, dc_offset_hi);
-       dprintk("Signal lvl over threshold: %d\n", signal_lv_over_threshold);
-       dprintk("VCO: %d, VCO Sub-band: %d, ADC: %d\n", vco, vco_sub_band, adc);
-}
-
-static int max2165_set_params(struct dvb_frontend *fe)
-{
-       struct max2165_priv *priv = fe->tuner_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret;
-
-       switch (c->bandwidth_hz) {
-       case 7000000:
-       case 8000000:
-               priv->frequency = c->frequency;
-               break;
-       default:
-               printk(KERN_INFO "MAX2165: bandwidth %d Hz not supported.\n",
-                      c->bandwidth_hz);
-               return -EINVAL;
-       }
-
-       dprintk("%s() frequency=%d\n", __func__, c->frequency);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       max2165_set_bandwidth(priv, c->bandwidth_hz);
-       ret = max2165_set_rf(priv, priv->frequency);
-       mdelay(50);
-       max2165_debug_status(priv);
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       if (ret != 0)
-               return -EREMOTEIO;
-
-       return 0;
-}
-
-static int max2165_get_frequency(struct dvb_frontend *fe, u32 *freq)
-{
-       struct max2165_priv *priv = fe->tuner_priv;
-       dprintk("%s()\n", __func__);
-       *freq = priv->frequency;
-       return 0;
-}
-
-static int max2165_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
-{
-       struct max2165_priv *priv = fe->tuner_priv;
-       dprintk("%s()\n", __func__);
-
-       *bw = priv->bandwidth;
-       return 0;
-}
-
-static int max2165_get_status(struct dvb_frontend *fe, u32 *status)
-{
-       struct max2165_priv *priv = fe->tuner_priv;
-       u16 lock_status = 0;
-
-       dprintk("%s()\n", __func__);
-
-       if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-
-       max2165_debug_status(priv);
-       *status = lock_status;
-
-       if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-
-       return 0;
-}
-
-static int max2165_sleep(struct dvb_frontend *fe)
-{
-       dprintk("%s()\n", __func__);
-       return 0;
-}
-
-static int max2165_init(struct dvb_frontend *fe)
-{
-       struct max2165_priv *priv = fe->tuner_priv;
-       dprintk("%s()\n", __func__);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       /* Setup initial values */
-       /* Fractional Mode on */
-       max2165_write_reg(priv, REG_NDIV_FRAC2, 0x18);
-       /* LNA on */
-       max2165_write_reg(priv, REG_LNA, 0x01);
-       max2165_write_reg(priv, REG_PLL_CFG, 0x7A);
-       max2165_write_reg(priv, REG_TEST, 0x08);
-       max2165_write_reg(priv, REG_SHUTDOWN, 0x40);
-       max2165_write_reg(priv, REG_VCO_CTRL, 0x84);
-       max2165_write_reg(priv, REG_BASEBAND_CTRL, 0xC3);
-       max2165_write_reg(priv, REG_DC_OFFSET_CTRL, 0x75);
-       max2165_write_reg(priv, REG_DC_OFFSET_DAC, 0x00);
-       max2165_write_reg(priv, REG_ROM_TABLE_ADDR, 0x00);
-
-       max2165_set_osc(priv, priv->config->osc_clk);
-
-       max2165_read_rom_table(priv);
-
-       max2165_set_bandwidth(priv, 8000000);
-
-       if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-
-       return 0;
-}
-
-static int max2165_release(struct dvb_frontend *fe)
-{
-       struct max2165_priv *priv = fe->tuner_priv;
-       dprintk("%s()\n", __func__);
-
-       kfree(priv);
-       fe->tuner_priv = NULL;
-
-       return 0;
-}
-
-static const struct dvb_tuner_ops max2165_tuner_ops = {
-       .info = {
-               .name           = "Maxim MAX2165",
-               .frequency_min  = 470000000,
-               .frequency_max  = 780000000,
-               .frequency_step =     50000,
-       },
-
-       .release           = max2165_release,
-       .init              = max2165_init,
-       .sleep             = max2165_sleep,
-
-       .set_params        = max2165_set_params,
-       .set_analog_params = NULL,
-       .get_frequency     = max2165_get_frequency,
-       .get_bandwidth     = max2165_get_bandwidth,
-       .get_status        = max2165_get_status
-};
-
-struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
-                                  struct i2c_adapter *i2c,
-                                  struct max2165_config *cfg)
-{
-       struct max2165_priv *priv = NULL;
-
-       dprintk("%s(%d-%04x)\n", __func__,
-               i2c ? i2c_adapter_id(i2c) : -1,
-               cfg ? cfg->i2c_address : -1);
-
-       priv = kzalloc(sizeof(struct max2165_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       memcpy(&fe->ops.tuner_ops, &max2165_tuner_ops,
-               sizeof(struct dvb_tuner_ops));
-
-       priv->config = cfg;
-       priv->i2c = i2c;
-       fe->tuner_priv = priv;
-
-       max2165_init(fe);
-       max2165_debug_status(priv);
-
-       return fe;
-}
-EXPORT_SYMBOL(max2165_attach);
-
-MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
-MODULE_DESCRIPTION("Maxim MAX2165 silicon tuner driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/max2165.h b/drivers/media/common/tuners/max2165.h
deleted file mode 100644 (file)
index c063c36..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *  Driver for Maxim MAX2165 silicon tuner
- *
- *  Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __MAX2165_H__
-#define __MAX2165_H__
-
-struct dvb_frontend;
-struct i2c_adapter;
-
-struct max2165_config {
-       u8 i2c_address;
-       u8 osc_clk; /* in MHz, selectable values: 4,16,18,20,22,24,26,28 */
-};
-
-#if defined(CONFIG_MEDIA_TUNER_MAX2165) || \
-    (defined(CONFIG_MEDIA_TUNER_MAX2165_MODULE) && defined(MODULE))
-extern struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
-       struct i2c_adapter *i2c,
-       struct max2165_config *cfg);
-#else
-static inline struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
-       struct i2c_adapter *i2c,
-       struct max2165_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif
diff --git a/drivers/media/common/tuners/max2165_priv.h b/drivers/media/common/tuners/max2165_priv.h
deleted file mode 100644 (file)
index 91bbe02..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *  Driver for Maxim MAX2165 silicon tuner
- *
- *  Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __MAX2165_PRIV_H__
-#define __MAX2165_PRIV_H__
-
-#define REG_NDIV_INT 0x00
-#define REG_NDIV_FRAC2 0x01
-#define REG_NDIV_FRAC1 0x02
-#define REG_NDIV_FRAC0 0x03
-#define REG_TRACK_FILTER 0x04
-#define REG_LNA 0x05
-#define REG_PLL_CFG 0x06
-#define REG_TEST 0x07
-#define REG_SHUTDOWN 0x08
-#define REG_VCO_CTRL 0x09
-#define REG_BASEBAND_CTRL 0x0A
-#define REG_DC_OFFSET_CTRL 0x0B
-#define REG_DC_OFFSET_DAC 0x0C
-#define REG_ROM_TABLE_ADDR 0x0D
-
-/* Read Only Registers */
-#define REG_ROM_TABLE_DATA 0x10
-#define REG_STATUS 0x11
-#define REG_AUTOTUNE 0x12
-
-struct max2165_priv {
-       struct max2165_config *config;
-       struct i2c_adapter *i2c;
-
-       u32 frequency;
-       u32 bandwidth;
-
-       u8 tf_ntch_low_cfg;
-       u8 tf_ntch_hi_cfg;
-       u8 tf_balun_low_ref;
-       u8 tf_balun_hi_ref;
-       u8 bb_filter_7mhz_cfg;
-       u8 bb_filter_8mhz_cfg;
-};
-
-#endif
diff --git a/drivers/media/common/tuners/mc44s803.c b/drivers/media/common/tuners/mc44s803.c
deleted file mode 100644 (file)
index 5ddce7e..0000000
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- *  Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
- *
- *  Copyright (c) 2009 Jochen Friedrich <jochen@scram.de>
- *
- *  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.=
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/dvb/frontend.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-
-#include "mc44s803.h"
-#include "mc44s803_priv.h"
-
-#define mc_printk(level, format, arg...)       \
-       printk(level "mc44s803: " format , ## arg)
-
-/* Writes a single register */
-static int mc44s803_writereg(struct mc44s803_priv *priv, u32 val)
-{
-       u8 buf[3];
-       struct i2c_msg msg = {
-               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 3
-       };
-
-       buf[0] = (val & 0xff0000) >> 16;
-       buf[1] = (val & 0xff00) >> 8;
-       buf[2] = (val & 0xff);
-
-       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
-               mc_printk(KERN_WARNING, "I2C write failed\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-/* Reads a single register */
-static int mc44s803_readreg(struct mc44s803_priv *priv, u8 reg, u32 *val)
-{
-       u32 wval;
-       u8 buf[3];
-       int ret;
-       struct i2c_msg msg[] = {
-               { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
-                 .buf = buf, .len = 3 },
-       };
-
-       wval = MC44S803_REG_SM(MC44S803_REG_DATAREG, MC44S803_ADDR) |
-              MC44S803_REG_SM(reg, MC44S803_D);
-
-       ret = mc44s803_writereg(priv, wval);
-       if (ret)
-               return ret;
-
-       if (i2c_transfer(priv->i2c, msg, 1) != 1) {
-               mc_printk(KERN_WARNING, "I2C read failed\n");
-               return -EREMOTEIO;
-       }
-
-       *val = (buf[0] << 16) | (buf[1] << 8) | buf[2];
-
-       return 0;
-}
-
-static int mc44s803_release(struct dvb_frontend *fe)
-{
-       struct mc44s803_priv *priv = fe->tuner_priv;
-
-       fe->tuner_priv = NULL;
-       kfree(priv);
-
-       return 0;
-}
-
-static int mc44s803_init(struct dvb_frontend *fe)
-{
-       struct mc44s803_priv *priv = fe->tuner_priv;
-       u32 val;
-       int err;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-/* Reset chip */
-       val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR) |
-             MC44S803_REG_SM(1, MC44S803_RS);
-
-       err = mc44s803_writereg(priv, val);
-       if (err)
-               goto exit;
-
-       val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR);
-
-       err = mc44s803_writereg(priv, val);
-       if (err)
-               goto exit;
-
-/* Power Up and Start Osc */
-
-       val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) |
-             MC44S803_REG_SM(0xC0, MC44S803_REFOSC) |
-             MC44S803_REG_SM(1, MC44S803_OSCSEL);
-
-       err = mc44s803_writereg(priv, val);
-       if (err)
-               goto exit;
-
-       val = MC44S803_REG_SM(MC44S803_REG_POWER, MC44S803_ADDR) |
-             MC44S803_REG_SM(0x200, MC44S803_POWER);
-
-       err = mc44s803_writereg(priv, val);
-       if (err)
-               goto exit;
-
-       msleep(10);
-
-       val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) |
-             MC44S803_REG_SM(0x40, MC44S803_REFOSC) |
-             MC44S803_REG_SM(1, MC44S803_OSCSEL);
-
-       err = mc44s803_writereg(priv, val);
-       if (err)
-               goto exit;
-
-       msleep(20);
-
-/* Setup Mixer */
-
-       val = MC44S803_REG_SM(MC44S803_REG_MIXER, MC44S803_ADDR) |
-             MC44S803_REG_SM(1, MC44S803_TRI_STATE) |
-             MC44S803_REG_SM(0x7F, MC44S803_MIXER_RES);
-
-       err = mc44s803_writereg(priv, val);
-       if (err)
-               goto exit;
-
-/* Setup Cirquit Adjust */
-
-       val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) |
-             MC44S803_REG_SM(1, MC44S803_G1) |
-             MC44S803_REG_SM(1, MC44S803_G3) |
-             MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) |
-             MC44S803_REG_SM(1, MC44S803_G6) |
-             MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) |
-             MC44S803_REG_SM(0x3, MC44S803_LP) |
-             MC44S803_REG_SM(1, MC44S803_CLRF) |
-             MC44S803_REG_SM(1, MC44S803_CLIF);
-
-       err = mc44s803_writereg(priv, val);
-       if (err)
-               goto exit;
-
-       val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) |
-             MC44S803_REG_SM(1, MC44S803_G1) |
-             MC44S803_REG_SM(1, MC44S803_G3) |
-             MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) |
-             MC44S803_REG_SM(1, MC44S803_G6) |
-             MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) |
-             MC44S803_REG_SM(0x3, MC44S803_LP);
-
-       err = mc44s803_writereg(priv, val);
-       if (err)
-               goto exit;
-
-/* Setup Digtune */
-
-       val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
-             MC44S803_REG_SM(3, MC44S803_XOD);
-
-       err = mc44s803_writereg(priv, val);
-       if (err)
-               goto exit;
-
-/* Setup AGC */
-
-       val = MC44S803_REG_SM(MC44S803_REG_LNAAGC, MC44S803_ADDR) |
-             MC44S803_REG_SM(1, MC44S803_AT1) |
-             MC44S803_REG_SM(1, MC44S803_AT2) |
-             MC44S803_REG_SM(1, MC44S803_AGC_AN_DIG) |
-             MC44S803_REG_SM(1, MC44S803_AGC_READ_EN) |
-             MC44S803_REG_SM(1, MC44S803_LNA0);
-
-       err = mc44s803_writereg(priv, val);
-       if (err)
-               goto exit;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-       return 0;
-
-exit:
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       mc_printk(KERN_WARNING, "I/O Error\n");
-       return err;
-}
-
-static int mc44s803_set_params(struct dvb_frontend *fe)
-{
-       struct mc44s803_priv *priv = fe->tuner_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u32 r1, r2, n1, n2, lo1, lo2, freq, val;
-       int err;
-
-       priv->frequency = c->frequency;
-
-       r1 = MC44S803_OSC / 1000000;
-       r2 = MC44S803_OSC /  100000;
-
-       n1 = (c->frequency + MC44S803_IF1 + 500000) / 1000000;
-       freq = MC44S803_OSC / r1 * n1;
-       lo1 = ((60 * n1) + (r1 / 2)) / r1;
-       freq = freq - c->frequency;
-
-       n2 = (freq - MC44S803_IF2 + 50000) / 100000;
-       lo2 = ((60 * n2) + (r2 / 2)) / r2;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       val = MC44S803_REG_SM(MC44S803_REG_REFDIV, MC44S803_ADDR) |
-             MC44S803_REG_SM(r1-1, MC44S803_R1) |
-             MC44S803_REG_SM(r2-1, MC44S803_R2) |
-             MC44S803_REG_SM(1, MC44S803_REFBUF_EN);
-
-       err = mc44s803_writereg(priv, val);
-       if (err)
-               goto exit;
-
-       val = MC44S803_REG_SM(MC44S803_REG_LO1, MC44S803_ADDR) |
-             MC44S803_REG_SM(n1-2, MC44S803_LO1);
-
-       err = mc44s803_writereg(priv, val);
-       if (err)
-               goto exit;
-
-       val = MC44S803_REG_SM(MC44S803_REG_LO2, MC44S803_ADDR) |
-             MC44S803_REG_SM(n2-2, MC44S803_LO2);
-
-       err = mc44s803_writereg(priv, val);
-       if (err)
-               goto exit;
-
-       val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
-             MC44S803_REG_SM(1, MC44S803_DA) |
-             MC44S803_REG_SM(lo1, MC44S803_LO_REF) |
-             MC44S803_REG_SM(1, MC44S803_AT);
-
-       err = mc44s803_writereg(priv, val);
-       if (err)
-               goto exit;
-
-       val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
-             MC44S803_REG_SM(2, MC44S803_DA) |
-             MC44S803_REG_SM(lo2, MC44S803_LO_REF) |
-             MC44S803_REG_SM(1, MC44S803_AT);
-
-       err = mc44s803_writereg(priv, val);
-       if (err)
-               goto exit;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       return 0;
-
-exit:
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       mc_printk(KERN_WARNING, "I/O Error\n");
-       return err;
-}
-
-static int mc44s803_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct mc44s803_priv *priv = fe->tuner_priv;
-       *frequency = priv->frequency;
-       return 0;
-}
-
-static const struct dvb_tuner_ops mc44s803_tuner_ops = {
-       .info = {
-               .name           = "Freescale MC44S803",
-               .frequency_min  =   48000000,
-               .frequency_max  = 1000000000,
-               .frequency_step =     100000,
-       },
-
-       .release       = mc44s803_release,
-       .init          = mc44s803_init,
-       .set_params    = mc44s803_set_params,
-       .get_frequency = mc44s803_get_frequency
-};
-
-/* This functions tries to identify a MC44S803 tuner by reading the ID
-   register. This is hasty. */
-struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
-        struct i2c_adapter *i2c, struct mc44s803_config *cfg)
-{
-       struct mc44s803_priv *priv;
-       u32 reg;
-       u8 id;
-       int ret;
-
-       reg = 0;
-
-       priv = kzalloc(sizeof(struct mc44s803_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->cfg = cfg;
-       priv->i2c = i2c;
-       priv->fe  = fe;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
-
-       ret = mc44s803_readreg(priv, MC44S803_REG_ID, &reg);
-       if (ret)
-               goto error;
-
-       id = MC44S803_REG_MS(reg, MC44S803_ID);
-
-       if (id != 0x14) {
-               mc_printk(KERN_ERR, "unsupported ID "
-                      "(%x should be 0x14)\n", id);
-               goto error;
-       }
-
-       mc_printk(KERN_INFO, "successfully identified (ID = %x)\n", id);
-       memcpy(&fe->ops.tuner_ops, &mc44s803_tuner_ops,
-              sizeof(struct dvb_tuner_ops));
-
-       fe->tuner_priv = priv;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
-
-       return fe;
-
-error:
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
-
-       kfree(priv);
-       return NULL;
-}
-EXPORT_SYMBOL(mc44s803_attach);
-
-MODULE_AUTHOR("Jochen Friedrich");
-MODULE_DESCRIPTION("Freescale MC44S803 silicon tuner driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/mc44s803.h b/drivers/media/common/tuners/mc44s803.h
deleted file mode 100644 (file)
index 34f3892..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
- *
- *  Copyright (c) 2009 Jochen Friedrich <jochen@scram.de>
- *
- *  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 MC44S803_H
-#define MC44S803_H
-
-struct dvb_frontend;
-struct i2c_adapter;
-
-struct mc44s803_config {
-       u8 i2c_address;
-       u8 dig_out;
-};
-
-#if defined(CONFIG_MEDIA_TUNER_MC44S803) || \
-    (defined(CONFIG_MEDIA_TUNER_MC44S803_MODULE) && defined(MODULE))
-extern struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
-        struct i2c_adapter *i2c, struct mc44s803_config *cfg);
-#else
-static inline struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
-        struct i2c_adapter *i2c, struct mc44s803_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_MEDIA_TUNER_MC44S803 */
-
-#endif
diff --git a/drivers/media/common/tuners/mc44s803_priv.h b/drivers/media/common/tuners/mc44s803_priv.h
deleted file mode 100644 (file)
index 14a9278..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- *  Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
- *
- *  Copyright (c) 2009 Jochen Friedrich <jochen@scram.de>
- *
- *  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 MC44S803_PRIV_H
-#define MC44S803_PRIV_H
-
-/* This driver is based on the information available in the datasheet
-   http://www.freescale.com/files/rf_if/doc/data_sheet/MC44S803.pdf
-
-   SPI or I2C Address : 0xc0-0xc6
-
-   Reg.No | Function
-   -------------------------------------------
-       00 | Power Down
-       01 | Reference Oszillator
-       02 | Reference Dividers
-       03 | Mixer and Reference Buffer
-       04 | Reset/Serial Out
-       05 | LO 1
-       06 | LO 2
-       07 | Circuit Adjust
-       08 | Test
-       09 | Digital Tune
-       0A | LNA AGC
-       0B | Data Register Address
-       0C | Regulator Test
-       0D | VCO Test
-       0E | LNA Gain/Input Power
-       0F | ID Bits
-
-*/
-
-#define MC44S803_OSC 26000000  /* 26 MHz */
-#define MC44S803_IF1 1086000000 /* 1086 MHz */
-#define MC44S803_IF2 36125000  /* 36.125 MHz */
-
-#define MC44S803_REG_POWER     0
-#define MC44S803_REG_REFOSC    1
-#define MC44S803_REG_REFDIV    2
-#define MC44S803_REG_MIXER     3
-#define MC44S803_REG_RESET     4
-#define MC44S803_REG_LO1       5
-#define MC44S803_REG_LO2       6
-#define MC44S803_REG_CIRCADJ   7
-#define MC44S803_REG_TEST      8
-#define MC44S803_REG_DIGTUNE   9
-#define MC44S803_REG_LNAAGC    0x0A
-#define MC44S803_REG_DATAREG   0x0B
-#define MC44S803_REG_REGTEST   0x0C
-#define MC44S803_REG_VCOTEST   0x0D
-#define MC44S803_REG_LNAGAIN   0x0E
-#define MC44S803_REG_ID                0x0F
-
-/* Register definitions */
-#define MC44S803_ADDR          0x0F
-#define MC44S803_ADDR_S                0
-/* REG_POWER */
-#define MC44S803_POWER         0xFFFFF0
-#define MC44S803_POWER_S       4
-/* REG_REFOSC */
-#define MC44S803_REFOSC                0x1FF0
-#define MC44S803_REFOSC_S      4
-#define MC44S803_OSCSEL                0x2000
-#define MC44S803_OSCSEL_S      13
-/* REG_REFDIV */
-#define MC44S803_R2            0x1FF0
-#define MC44S803_R2_S          4
-#define MC44S803_REFBUF_EN     0x2000
-#define MC44S803_REFBUF_EN_S   13
-#define MC44S803_R1            0x7C000
-#define MC44S803_R1_S          14
-/* REG_MIXER */
-#define MC44S803_R3            0x70
-#define MC44S803_R3_S          4
-#define MC44S803_MUX3          0x80
-#define MC44S803_MUX3_S                7
-#define MC44S803_MUX4          0x100
-#define MC44S803_MUX4_S                8
-#define MC44S803_OSC_SCR       0x200
-#define MC44S803_OSC_SCR_S     9
-#define MC44S803_TRI_STATE     0x400
-#define MC44S803_TRI_STATE_S   10
-#define MC44S803_BUF_GAIN      0x800
-#define MC44S803_BUF_GAIN_S    11
-#define MC44S803_BUF_IO                0x1000
-#define MC44S803_BUF_IO_S      12
-#define MC44S803_MIXER_RES     0xFE000
-#define MC44S803_MIXER_RES_S   13
-/* REG_RESET */
-#define MC44S803_RS            0x10
-#define MC44S803_RS_S          4
-#define MC44S803_SO            0x20
-#define MC44S803_SO_S          5
-/* REG_LO1 */
-#define MC44S803_LO1           0xFFF0
-#define MC44S803_LO1_S         4
-/* REG_LO2 */
-#define MC44S803_LO2           0x7FFF0
-#define MC44S803_LO2_S         4
-/* REG_CIRCADJ */
-#define MC44S803_G1            0x20
-#define MC44S803_G1_S          5
-#define MC44S803_G3            0x80
-#define MC44S803_G3_S          7
-#define MC44S803_CIRCADJ_RES   0x300
-#define MC44S803_CIRCADJ_RES_S 8
-#define MC44S803_G6            0x400
-#define MC44S803_G6_S          10
-#define MC44S803_G7            0x800
-#define MC44S803_G7_S          11
-#define MC44S803_S1            0x1000
-#define MC44S803_S1_S          12
-#define MC44S803_LP            0x7E000
-#define MC44S803_LP_S          13
-#define MC44S803_CLRF          0x80000
-#define MC44S803_CLRF_S                19
-#define MC44S803_CLIF          0x100000
-#define MC44S803_CLIF_S                20
-/* REG_TEST */
-/* REG_DIGTUNE */
-#define MC44S803_DA            0xF0
-#define MC44S803_DA_S          4
-#define MC44S803_XOD           0x300
-#define MC44S803_XOD_S         8
-#define MC44S803_RST           0x10000
-#define MC44S803_RST_S         16
-#define MC44S803_LO_REF                0x1FFF00
-#define MC44S803_LO_REF_S      8
-#define MC44S803_AT            0x200000
-#define MC44S803_AT_S          21
-#define MC44S803_MT            0x400000
-#define MC44S803_MT_S          22
-/* REG_LNAAGC */
-#define MC44S803_G             0x3F0
-#define MC44S803_G_S           4
-#define MC44S803_AT1           0x400
-#define MC44S803_AT1_S         10
-#define MC44S803_AT2           0x800
-#define MC44S803_AT2_S         11
-#define MC44S803_HL_GR_EN      0x8000
-#define MC44S803_HL_GR_EN_S    15
-#define MC44S803_AGC_AN_DIG    0x10000
-#define MC44S803_AGC_AN_DIG_S  16
-#define MC44S803_ATTEN_EN      0x20000
-#define MC44S803_ATTEN_EN_S    17
-#define MC44S803_AGC_READ_EN   0x40000
-#define MC44S803_AGC_READ_EN_S 18
-#define MC44S803_LNA0          0x80000
-#define MC44S803_LNA0_S                19
-#define MC44S803_AGC_SEL       0x100000
-#define MC44S803_AGC_SEL_S     20
-#define MC44S803_AT0           0x200000
-#define MC44S803_AT0_S         21
-#define MC44S803_B             0xC00000
-#define MC44S803_B_S           22
-/* REG_DATAREG */
-#define MC44S803_D             0xF0
-#define MC44S803_D_S           4
-/* REG_REGTEST */
-/* REG_VCOTEST */
-/* REG_LNAGAIN */
-#define MC44S803_IF_PWR                0x700
-#define MC44S803_IF_PWR_S      8
-#define MC44S803_RF_PWR                0x3800
-#define MC44S803_RF_PWR_S      11
-#define MC44S803_LNA_GAIN      0xFC000
-#define MC44S803_LNA_GAIN_S    14
-/* REG_ID */
-#define MC44S803_ID            0x3E00
-#define MC44S803_ID_S          9
-
-/* Some macros to read/write fields */
-
-/* First shift, then mask */
-#define MC44S803_REG_SM(_val, _reg)                                    \
-       (((_val) << _reg##_S) & (_reg))
-
-/* First mask, then shift */
-#define MC44S803_REG_MS(_val, _reg)                                    \
-       (((_val) & (_reg)) >> _reg##_S)
-
-struct mc44s803_priv {
-       struct mc44s803_config *cfg;
-       struct i2c_adapter *i2c;
-       struct dvb_frontend *fe;
-
-       u32 frequency;
-};
-
-#endif
diff --git a/drivers/media/common/tuners/mt2060.c b/drivers/media/common/tuners/mt2060.c
deleted file mode 100644 (file)
index 13381de..0000000
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- *  Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
- *
- *  Copyright (c) 2006 Olivier DANET <odanet@caramail.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.=
- */
-
-/* In that file, frequencies are expressed in kiloHertz to avoid 32 bits overflows */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/dvb/frontend.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-
-#include "mt2060.h"
-#include "mt2060_priv.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-#define dprintk(args...) do { if (debug) {printk(KERN_DEBUG "MT2060: " args); printk("\n"); }} while (0)
-
-// Reads a single register
-static int mt2060_readreg(struct mt2060_priv *priv, u8 reg, u8 *val)
-{
-       struct i2c_msg msg[2] = {
-               { .addr = priv->cfg->i2c_address, .flags = 0,        .buf = &reg, .len = 1 },
-               { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val,  .len = 1 },
-       };
-
-       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
-               printk(KERN_WARNING "mt2060 I2C read failed\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-// Writes a single register
-static int mt2060_writereg(struct mt2060_priv *priv, u8 reg, u8 val)
-{
-       u8 buf[2] = { reg, val };
-       struct i2c_msg msg = {
-               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2
-       };
-
-       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
-               printk(KERN_WARNING "mt2060 I2C write failed\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-// Writes a set of consecutive registers
-static int mt2060_writeregs(struct mt2060_priv *priv,u8 *buf, u8 len)
-{
-       struct i2c_msg msg = {
-               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = len
-       };
-       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
-               printk(KERN_WARNING "mt2060 I2C write failed (len=%i)\n",(int)len);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-// Initialisation sequences
-// LNABAND=3, NUM1=0x3C, DIV1=0x74, NUM2=0x1080, DIV2=0x49
-static u8 mt2060_config1[] = {
-       REG_LO1C1,
-       0x3F,   0x74,   0x00,   0x08,   0x93
-};
-
-// FMCG=2, GP2=0, GP1=0
-static u8 mt2060_config2[] = {
-       REG_MISC_CTRL,
-       0x20,   0x1E,   0x30,   0xff,   0x80,   0xff,   0x00,   0x2c,   0x42
-};
-
-//  VGAG=3, V1CSE=1
-
-#ifdef  MT2060_SPURCHECK
-/* The function below calculates the frequency offset between the output frequency if2
- and the closer cross modulation subcarrier between lo1 and lo2 up to the tenth harmonic */
-static int mt2060_spurcalc(u32 lo1,u32 lo2,u32 if2)
-{
-       int I,J;
-       int dia,diamin,diff;
-       diamin=1000000;
-       for (I = 1; I < 10; I++) {
-               J = ((2*I*lo1)/lo2+1)/2;
-               diff = I*(int)lo1-J*(int)lo2;
-               if (diff < 0) diff=-diff;
-               dia = (diff-(int)if2);
-               if (dia < 0) dia=-dia;
-               if (diamin > dia) diamin=dia;
-       }
-       return diamin;
-}
-
-#define BANDWIDTH 4000 // kHz
-
-/* Calculates the frequency offset to add to avoid spurs. Returns 0 if no offset is needed */
-static int mt2060_spurcheck(u32 lo1,u32 lo2,u32 if2)
-{
-       u32 Spur,Sp1,Sp2;
-       int I,J;
-       I=0;
-       J=1000;
-
-       Spur=mt2060_spurcalc(lo1,lo2,if2);
-       if (Spur < BANDWIDTH) {
-               /* Potential spurs detected */
-               dprintk("Spurs before : f_lo1: %d  f_lo2: %d  (kHz)",
-                       (int)lo1,(int)lo2);
-               I=1000;
-               Sp1 = mt2060_spurcalc(lo1+I,lo2+I,if2);
-               Sp2 = mt2060_spurcalc(lo1-I,lo2-I,if2);
-
-               if (Sp1 < Sp2) {
-                       J=-J; I=-I; Spur=Sp2;
-               } else
-                       Spur=Sp1;
-
-               while (Spur < BANDWIDTH) {
-                       I += J;
-                       Spur = mt2060_spurcalc(lo1+I,lo2+I,if2);
-               }
-               dprintk("Spurs after  : f_lo1: %d  f_lo2: %d  (kHz)",
-                       (int)(lo1+I),(int)(lo2+I));
-       }
-       return I;
-}
-#endif
-
-#define IF2  36150       // IF2 frequency = 36.150 MHz
-#define FREF 16000       // Quartz oscillator 16 MHz
-
-static int mt2060_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct mt2060_priv *priv;
-       int ret=0;
-       int i=0;
-       u32 freq;
-       u8  lnaband;
-       u32 f_lo1,f_lo2;
-       u32 div1,num1,div2,num2;
-       u8  b[8];
-       u32 if1;
-
-       priv = fe->tuner_priv;
-
-       if1 = priv->if1_freq;
-       b[0] = REG_LO1B1;
-       b[1] = 0xFF;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
-
-       mt2060_writeregs(priv,b,2);
-
-       freq = c->frequency / 1000; /* Hz -> kHz */
-
-       f_lo1 = freq + if1 * 1000;
-       f_lo1 = (f_lo1 / 250) * 250;
-       f_lo2 = f_lo1 - freq - IF2;
-       // From the Comtech datasheet, the step used is 50kHz. The tuner chip could be more precise
-       f_lo2 = ((f_lo2 + 25) / 50) * 50;
-       priv->frequency =  (f_lo1 - f_lo2 - IF2) * 1000,
-
-#ifdef MT2060_SPURCHECK
-       // LO-related spurs detection and correction
-       num1   = mt2060_spurcheck(f_lo1,f_lo2,IF2);
-       f_lo1 += num1;
-       f_lo2 += num1;
-#endif
-       //Frequency LO1 = 16MHz * (DIV1 + NUM1/64 )
-       num1 = f_lo1 / (FREF / 64);
-       div1 = num1 / 64;
-       num1 &= 0x3f;
-
-       // Frequency LO2 = 16MHz * (DIV2 + NUM2/8192 )
-       num2 = f_lo2 * 64 / (FREF / 128);
-       div2 = num2 / 8192;
-       num2 &= 0x1fff;
-
-       if (freq <=  95000) lnaband = 0xB0; else
-       if (freq <= 180000) lnaband = 0xA0; else
-       if (freq <= 260000) lnaband = 0x90; else
-       if (freq <= 335000) lnaband = 0x80; else
-       if (freq <= 425000) lnaband = 0x70; else
-       if (freq <= 480000) lnaband = 0x60; else
-       if (freq <= 570000) lnaband = 0x50; else
-       if (freq <= 645000) lnaband = 0x40; else
-       if (freq <= 730000) lnaband = 0x30; else
-       if (freq <= 810000) lnaband = 0x20; else lnaband = 0x10;
-
-       b[0] = REG_LO1C1;
-       b[1] = lnaband | ((num1 >>2) & 0x0F);
-       b[2] = div1;
-       b[3] = (num2 & 0x0F)  | ((num1 & 3) << 4);
-       b[4] = num2 >> 4;
-       b[5] = ((num2 >>12) & 1) | (div2 << 1);
-
-       dprintk("IF1: %dMHz",(int)if1);
-       dprintk("PLL freq=%dkHz  f_lo1=%dkHz  f_lo2=%dkHz",(int)freq,(int)f_lo1,(int)f_lo2);
-       dprintk("PLL div1=%d  num1=%d  div2=%d  num2=%d",(int)div1,(int)num1,(int)div2,(int)num2);
-       dprintk("PLL [1..5]: %2x %2x %2x %2x %2x",(int)b[1],(int)b[2],(int)b[3],(int)b[4],(int)b[5]);
-
-       mt2060_writeregs(priv,b,6);
-
-       //Waits for pll lock or timeout
-       i = 0;
-       do {
-               mt2060_readreg(priv,REG_LO_STATUS,b);
-               if ((b[0] & 0x88)==0x88)
-                       break;
-               msleep(4);
-               i++;
-       } while (i<10);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
-
-       return ret;
-}
-
-static void mt2060_calibrate(struct mt2060_priv *priv)
-{
-       u8 b = 0;
-       int i = 0;
-
-       if (mt2060_writeregs(priv,mt2060_config1,sizeof(mt2060_config1)))
-               return;
-       if (mt2060_writeregs(priv,mt2060_config2,sizeof(mt2060_config2)))
-               return;
-
-       /* initialize the clock output */
-       mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x30);
-
-       do {
-               b |= (1 << 6); // FM1SS;
-               mt2060_writereg(priv, REG_LO2C1,b);
-               msleep(20);
-
-               if (i == 0) {
-                       b |= (1 << 7); // FM1CA;
-                       mt2060_writereg(priv, REG_LO2C1,b);
-                       b &= ~(1 << 7); // FM1CA;
-                       msleep(20);
-               }
-
-               b &= ~(1 << 6); // FM1SS
-               mt2060_writereg(priv, REG_LO2C1,b);
-
-               msleep(20);
-               i++;
-       } while (i < 9);
-
-       i = 0;
-       while (i++ < 10 && mt2060_readreg(priv, REG_MISC_STAT, &b) == 0 && (b & (1 << 6)) == 0)
-               msleep(20);
-
-       if (i <= 10) {
-               mt2060_readreg(priv, REG_FM_FREQ, &priv->fmfreq); // now find out, what is fmreq used for :)
-               dprintk("calibration was successful: %d", (int)priv->fmfreq);
-       } else
-               dprintk("FMCAL timed out");
-}
-
-static int mt2060_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct mt2060_priv *priv = fe->tuner_priv;
-       *frequency = priv->frequency;
-       return 0;
-}
-
-static int mt2060_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       *frequency = IF2 * 1000;
-       return 0;
-}
-
-static int mt2060_init(struct dvb_frontend *fe)
-{
-       struct mt2060_priv *priv = fe->tuner_priv;
-       int ret;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
-
-       ret = mt2060_writereg(priv, REG_VGAG,
-                             (priv->cfg->clock_out << 6) | 0x33);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
-
-       return ret;
-}
-
-static int mt2060_sleep(struct dvb_frontend *fe)
-{
-       struct mt2060_priv *priv = fe->tuner_priv;
-       int ret;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
-
-       ret = mt2060_writereg(priv, REG_VGAG,
-                             (priv->cfg->clock_out << 6) | 0x30);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
-
-       return ret;
-}
-
-static int mt2060_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static const struct dvb_tuner_ops mt2060_tuner_ops = {
-       .info = {
-               .name           = "Microtune MT2060",
-               .frequency_min  =  48000000,
-               .frequency_max  = 860000000,
-               .frequency_step =     50000,
-       },
-
-       .release       = mt2060_release,
-
-       .init          = mt2060_init,
-       .sleep         = mt2060_sleep,
-
-       .set_params    = mt2060_set_params,
-       .get_frequency = mt2060_get_frequency,
-       .get_if_frequency = mt2060_get_if_frequency,
-};
-
-/* This functions tries to identify a MT2060 tuner by reading the PART/REV register. This is hasty. */
-struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
-{
-       struct mt2060_priv *priv = NULL;
-       u8 id = 0;
-
-       priv = kzalloc(sizeof(struct mt2060_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->cfg      = cfg;
-       priv->i2c      = i2c;
-       priv->if1_freq = if1;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
-
-       if (mt2060_readreg(priv,REG_PART_REV,&id) != 0) {
-               kfree(priv);
-               return NULL;
-       }
-
-       if (id != PART_REV) {
-               kfree(priv);
-               return NULL;
-       }
-       printk(KERN_INFO "MT2060: successfully identified (IF1 = %d)\n", if1);
-       memcpy(&fe->ops.tuner_ops, &mt2060_tuner_ops, sizeof(struct dvb_tuner_ops));
-
-       fe->tuner_priv = priv;
-
-       mt2060_calibrate(priv);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
-
-       return fe;
-}
-EXPORT_SYMBOL(mt2060_attach);
-
-MODULE_AUTHOR("Olivier DANET");
-MODULE_DESCRIPTION("Microtune MT2060 silicon tuner driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/mt2060.h b/drivers/media/common/tuners/mt2060.h
deleted file mode 100644 (file)
index cb60caf..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- *  Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
- *
- *  Copyright (c) 2006 Olivier DANET <odanet@caramail.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 MT2060_H
-#define MT2060_H
-
-struct dvb_frontend;
-struct i2c_adapter;
-
-struct mt2060_config {
-       u8 i2c_address;
-       u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
-};
-
-#if defined(CONFIG_MEDIA_TUNER_MT2060) || (defined(CONFIG_MEDIA_TUNER_MT2060_MODULE) && defined(MODULE))
-extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1);
-#else
-static inline struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_MEDIA_TUNER_MT2060
-
-#endif
diff --git a/drivers/media/common/tuners/mt2060_priv.h b/drivers/media/common/tuners/mt2060_priv.h
deleted file mode 100644 (file)
index 2b60de6..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- *  Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
- *
- *  Copyright (c) 2006 Olivier DANET <odanet@caramail.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 MT2060_PRIV_H
-#define MT2060_PRIV_H
-
-// Uncomment the #define below to enable spurs checking. The results where quite unconvincing.
-// #define MT2060_SPURCHECK
-
-/* This driver is based on the information available in the datasheet of the
-   "Comtech SDVBT-3K6M" tuner ( K1000737843.pdf ) which features the MT2060 register map :
-
-   I2C Address : 0x60
-
-   Reg.No |   B7   |   B6   |   B5   |   B4   |   B3   |   B2   |   B1   |   B0   | ( defaults )
-   --------------------------------------------------------------------------------
-       00 | [              PART             ] | [              REV              ] | R  = 0x63
-       01 | [             LNABAND           ] | [              NUM1(5:2)        ] | RW = 0x3F
-       02 | [                               DIV1                                ] | RW = 0x74
-       03 | FM1CA  | FM1SS  | [  NUM1(1:0)  ] | [              NUM2(3:0)        ] | RW = 0x00
-       04 |                                 NUM2(11:4)                          ] | RW = 0x08
-       05 | [                               DIV2                       ] |NUM2(12)| RW = 0x93
-       06 | L1LK   | [        TAD1          ] | L2LK   | [         TAD2         ] | R
-       07 | [                               FMF                                 ] | R
-       08 |   ?    | FMCAL  |   ?    |   ?    |   ?    |   ?    |   ?    | TEMP   | R
-       09 |   0    |   0    | [    FMGC     ] |   0    | GP02   | GP01   |   0    | RW = 0x20
-       0A | ??
-       0B |   0    |   0    |   1    |   1    |   0    |   0    | [   VGAG      ] | RW = 0x30
-       0C | V1CSE  |   1    |   1    |   1    |   1    |   1    |   1    |   1    | RW = 0xFF
-       0D |   1    |   0    | [                      V1CS                       ] | RW = 0xB0
-       0E | ??
-       0F | ??
-       10 | ??
-       11 | [             LOTO              ] |   0    |   0    |   1    |   0    | RW = 0x42
-
-       PART    : Part code      : 6 for MT2060
-       REV     : Revision code  : 3 for current revision
-       LNABAND : Input frequency range : ( See code for details )
-       NUM1 / DIV1 / NUM2 / DIV2 : Frequencies programming ( See code for details )
-       FM1CA  : Calibration Start Bit
-       FM1SS  : Calibration Single Step bit
-       L1LK   : LO1 Lock Detect
-       TAD1   : Tune Line ADC ( ? )
-       L2LK   : LO2 Lock Detect
-       TAD2   : Tune Line ADC ( ? )
-       FMF    : Estimated first IF Center frequency Offset ( ? )
-       FM1CAL : Calibration done bit
-       TEMP   : On chip temperature sensor
-       FMCG   : Mixer 1 Cap Gain ( ? )
-       GP01 / GP02 : Programmable digital outputs. Unconnected pins ?
-       V1CSE  : LO1 VCO Automatic Capacitor Select Enable ( ? )
-       V1CS   : LO1 Capacitor Selection Value ( ? )
-       LOTO   : LO Timeout ( ? )
-       VGAG   : Tuner Output gain
-*/
-
-#define I2C_ADDRESS 0x60
-
-#define REG_PART_REV   0
-#define REG_LO1C1      1
-#define REG_LO1C2      2
-#define REG_LO2C1      3
-#define REG_LO2C2      4
-#define REG_LO2C3      5
-#define REG_LO_STATUS  6
-#define REG_FM_FREQ    7
-#define REG_MISC_STAT  8
-#define REG_MISC_CTRL  9
-#define REG_RESERVED_A 0x0A
-#define REG_VGAG       0x0B
-#define REG_LO1B1      0x0C
-#define REG_LO1B2      0x0D
-#define REG_LOTO       0x11
-
-#define PART_REV 0x63 // The current driver works only with PART=6 and REV=3 chips
-
-struct mt2060_priv {
-       struct mt2060_config *cfg;
-       struct i2c_adapter   *i2c;
-
-       u32 frequency;
-       u16 if1_freq;
-       u8  fmfreq;
-};
-
-#endif
diff --git a/drivers/media/common/tuners/mt2063.c b/drivers/media/common/tuners/mt2063.c
deleted file mode 100644 (file)
index 0ed9091..0000000
+++ /dev/null
@@ -1,2307 +0,0 @@
-/*
- * Driver for mt2063 Micronas tuner
- *
- * Copyright (c) 2011 Mauro Carvalho Chehab <mchehab@redhat.com>
- *
- * This driver came from a driver originally written by:
- *             Henry Wang <Henry.wang@AzureWave.com>
- * Made publicly available by Terratec, at:
- *     http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz
- * The original driver's license is GPL, as declared with MODULE_LICENSE()
- *
- * 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 under version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/videodev2.h>
-
-#include "mt2063.h"
-
-static unsigned int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Set Verbosity level");
-
-#define dprintk(level, fmt, arg...) do {                               \
-if (debug >= level)                                                    \
-       printk(KERN_DEBUG "mt2063 %s: " fmt, __func__, ## arg); \
-} while (0)
-
-
-/* positive error codes used internally */
-
-/*  Info: Unavoidable LO-related spur may be present in the output  */
-#define MT2063_SPUR_PRESENT_ERR             (0x00800000)
-
-/*  Info: Mask of bits used for # of LO-related spurs that were avoided during tuning  */
-#define MT2063_SPUR_CNT_MASK                (0x001f0000)
-#define MT2063_SPUR_SHIFT                   (16)
-
-/*  Info: Upconverter frequency is out of range (may be reason for MT_UPC_UNLOCK) */
-#define MT2063_UPC_RANGE                    (0x04000000)
-
-/*  Info: Downconverter frequency is out of range (may be reason for MT_DPC_UNLOCK) */
-#define MT2063_DNC_RANGE                    (0x08000000)
-
-/*
- *  Constant defining the version of the following structure
- *  and therefore the API for this code.
- *
- *  When compiling the tuner driver, the preprocessor will
- *  check against this version number to make sure that
- *  it matches the version that the tuner driver knows about.
- */
-
-/* DECT Frequency Avoidance */
-#define MT2063_DECT_AVOID_US_FREQS      0x00000001
-
-#define MT2063_DECT_AVOID_EURO_FREQS    0x00000002
-
-#define MT2063_EXCLUDE_US_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_US_FREQS) != 0)
-
-#define MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_EURO_FREQS) != 0)
-
-enum MT2063_DECT_Avoid_Type {
-       MT2063_NO_DECT_AVOIDANCE = 0,                           /* Do not create DECT exclusion zones.     */
-       MT2063_AVOID_US_DECT = MT2063_DECT_AVOID_US_FREQS,      /* Avoid US DECT frequencies.              */
-       MT2063_AVOID_EURO_DECT = MT2063_DECT_AVOID_EURO_FREQS,  /* Avoid European DECT frequencies.        */
-       MT2063_AVOID_BOTH                                       /* Avoid both regions. Not typically used. */
-};
-
-#define MT2063_MAX_ZONES 48
-
-struct MT2063_ExclZone_t {
-       u32 min_;
-       u32 max_;
-       struct MT2063_ExclZone_t *next_;
-};
-
-/*
- *  Structure of data needed for Spur Avoidance
- */
-struct MT2063_AvoidSpursData_t {
-       u32 f_ref;
-       u32 f_in;
-       u32 f_LO1;
-       u32 f_if1_Center;
-       u32 f_if1_Request;
-       u32 f_if1_bw;
-       u32 f_LO2;
-       u32 f_out;
-       u32 f_out_bw;
-       u32 f_LO1_Step;
-       u32 f_LO2_Step;
-       u32 f_LO1_FracN_Avoid;
-       u32 f_LO2_FracN_Avoid;
-       u32 f_zif_bw;
-       u32 f_min_LO_Separation;
-       u32 maxH1;
-       u32 maxH2;
-       enum MT2063_DECT_Avoid_Type avoidDECT;
-       u32 bSpurPresent;
-       u32 bSpurAvoided;
-       u32 nSpursFound;
-       u32 nZones;
-       struct MT2063_ExclZone_t *freeZones;
-       struct MT2063_ExclZone_t *usedZones;
-       struct MT2063_ExclZone_t MT2063_ExclZones[MT2063_MAX_ZONES];
-};
-
-/*
- * Parameter for function MT2063_SetPowerMask that specifies the power down
- * of various sections of the MT2063.
- */
-enum MT2063_Mask_Bits {
-       MT2063_REG_SD = 0x0040,         /* Shutdown regulator                 */
-       MT2063_SRO_SD = 0x0020,         /* Shutdown SRO                       */
-       MT2063_AFC_SD = 0x0010,         /* Shutdown AFC A/D                   */
-       MT2063_PD_SD = 0x0002,          /* Enable power detector shutdown     */
-       MT2063_PDADC_SD = 0x0001,       /* Enable power detector A/D shutdown */
-       MT2063_VCO_SD = 0x8000,         /* Enable VCO shutdown                */
-       MT2063_LTX_SD = 0x4000,         /* Enable LTX shutdown                */
-       MT2063_LT1_SD = 0x2000,         /* Enable LT1 shutdown                */
-       MT2063_LNA_SD = 0x1000,         /* Enable LNA shutdown                */
-       MT2063_UPC_SD = 0x0800,         /* Enable upconverter shutdown        */
-       MT2063_DNC_SD = 0x0400,         /* Enable downconverter shutdown      */
-       MT2063_VGA_SD = 0x0200,         /* Enable VGA shutdown                */
-       MT2063_AMP_SD = 0x0100,         /* Enable AMP shutdown                */
-       MT2063_ALL_SD = 0xFF73,         /* All shutdown bits for this tuner   */
-       MT2063_NONE_SD = 0x0000         /* No shutdown bits                   */
-};
-
-/*
- *  Possible values for MT2063_DNC_OUTPUT
- */
-enum MT2063_DNC_Output_Enable {
-       MT2063_DNC_NONE = 0,
-       MT2063_DNC_1,
-       MT2063_DNC_2,
-       MT2063_DNC_BOTH
-};
-
-/*
- *  Two-wire serial bus subaddresses of the tuner registers.
- *  Also known as the tuner's register addresses.
- */
-enum MT2063_Register_Offsets {
-       MT2063_REG_PART_REV = 0,        /*  0x00: Part/Rev Code         */
-       MT2063_REG_LO1CQ_1,             /*  0x01: LO1C Queued Byte 1    */
-       MT2063_REG_LO1CQ_2,             /*  0x02: LO1C Queued Byte 2    */
-       MT2063_REG_LO2CQ_1,             /*  0x03: LO2C Queued Byte 1    */
-       MT2063_REG_LO2CQ_2,             /*  0x04: LO2C Queued Byte 2    */
-       MT2063_REG_LO2CQ_3,             /*  0x05: LO2C Queued Byte 3    */
-       MT2063_REG_RSVD_06,             /*  0x06: Reserved              */
-       MT2063_REG_LO_STATUS,           /*  0x07: LO Status             */
-       MT2063_REG_FIFFC,               /*  0x08: FIFF Center           */
-       MT2063_REG_CLEARTUNE,           /*  0x09: ClearTune Filter      */
-       MT2063_REG_ADC_OUT,             /*  0x0A: ADC_OUT               */
-       MT2063_REG_LO1C_1,              /*  0x0B: LO1C Byte 1           */
-       MT2063_REG_LO1C_2,              /*  0x0C: LO1C Byte 2           */
-       MT2063_REG_LO2C_1,              /*  0x0D: LO2C Byte 1           */
-       MT2063_REG_LO2C_2,              /*  0x0E: LO2C Byte 2           */
-       MT2063_REG_LO2C_3,              /*  0x0F: LO2C Byte 3           */
-       MT2063_REG_RSVD_10,             /*  0x10: Reserved              */
-       MT2063_REG_PWR_1,               /*  0x11: PWR Byte 1            */
-       MT2063_REG_PWR_2,               /*  0x12: PWR Byte 2            */
-       MT2063_REG_TEMP_STATUS,         /*  0x13: Temp Status           */
-       MT2063_REG_XO_STATUS,           /*  0x14: Crystal Status        */
-       MT2063_REG_RF_STATUS,           /*  0x15: RF Attn Status        */
-       MT2063_REG_FIF_STATUS,          /*  0x16: FIF Attn Status       */
-       MT2063_REG_LNA_OV,              /*  0x17: LNA Attn Override     */
-       MT2063_REG_RF_OV,               /*  0x18: RF Attn Override      */
-       MT2063_REG_FIF_OV,              /*  0x19: FIF Attn Override     */
-       MT2063_REG_LNA_TGT,             /*  0x1A: Reserved              */
-       MT2063_REG_PD1_TGT,             /*  0x1B: Pwr Det 1 Target      */
-       MT2063_REG_PD2_TGT,             /*  0x1C: Pwr Det 2 Target      */
-       MT2063_REG_RSVD_1D,             /*  0x1D: Reserved              */
-       MT2063_REG_RSVD_1E,             /*  0x1E: Reserved              */
-       MT2063_REG_RSVD_1F,             /*  0x1F: Reserved              */
-       MT2063_REG_RSVD_20,             /*  0x20: Reserved              */
-       MT2063_REG_BYP_CTRL,            /*  0x21: Bypass Control        */
-       MT2063_REG_RSVD_22,             /*  0x22: Reserved              */
-       MT2063_REG_RSVD_23,             /*  0x23: Reserved              */
-       MT2063_REG_RSVD_24,             /*  0x24: Reserved              */
-       MT2063_REG_RSVD_25,             /*  0x25: Reserved              */
-       MT2063_REG_RSVD_26,             /*  0x26: Reserved              */
-       MT2063_REG_RSVD_27,             /*  0x27: Reserved              */
-       MT2063_REG_FIFF_CTRL,           /*  0x28: FIFF Control          */
-       MT2063_REG_FIFF_OFFSET,         /*  0x29: FIFF Offset           */
-       MT2063_REG_CTUNE_CTRL,          /*  0x2A: Reserved              */
-       MT2063_REG_CTUNE_OV,            /*  0x2B: Reserved              */
-       MT2063_REG_CTRL_2C,             /*  0x2C: Reserved              */
-       MT2063_REG_FIFF_CTRL2,          /*  0x2D: Fiff Control          */
-       MT2063_REG_RSVD_2E,             /*  0x2E: Reserved              */
-       MT2063_REG_DNC_GAIN,            /*  0x2F: DNC Control           */
-       MT2063_REG_VGA_GAIN,            /*  0x30: VGA Gain Ctrl         */
-       MT2063_REG_RSVD_31,             /*  0x31: Reserved              */
-       MT2063_REG_TEMP_SEL,            /*  0x32: Temperature Selection */
-       MT2063_REG_RSVD_33,             /*  0x33: Reserved              */
-       MT2063_REG_RSVD_34,             /*  0x34: Reserved              */
-       MT2063_REG_RSVD_35,             /*  0x35: Reserved              */
-       MT2063_REG_RSVD_36,             /*  0x36: Reserved              */
-       MT2063_REG_RSVD_37,             /*  0x37: Reserved              */
-       MT2063_REG_RSVD_38,             /*  0x38: Reserved              */
-       MT2063_REG_RSVD_39,             /*  0x39: Reserved              */
-       MT2063_REG_RSVD_3A,             /*  0x3A: Reserved              */
-       MT2063_REG_RSVD_3B,             /*  0x3B: Reserved              */
-       MT2063_REG_RSVD_3C,             /*  0x3C: Reserved              */
-       MT2063_REG_END_REGS
-};
-
-struct mt2063_state {
-       struct i2c_adapter *i2c;
-
-       bool init;
-
-       const struct mt2063_config *config;
-       struct dvb_tuner_ops ops;
-       struct dvb_frontend *frontend;
-       struct tuner_state status;
-
-       u32 frequency;
-       u32 srate;
-       u32 bandwidth;
-       u32 reference;
-
-       u32 tuner_id;
-       struct MT2063_AvoidSpursData_t AS_Data;
-       u32 f_IF1_actual;
-       u32 rcvr_mode;
-       u32 ctfilt_sw;
-       u32 CTFiltMax[31];
-       u32 num_regs;
-       u8 reg[MT2063_REG_END_REGS];
-};
-
-/*
- * mt2063_write - Write data into the I2C bus
- */
-static u32 mt2063_write(struct mt2063_state *state, u8 reg, u8 *data, u32 len)
-{
-       struct dvb_frontend *fe = state->frontend;
-       int ret;
-       u8 buf[60];
-       struct i2c_msg msg = {
-               .addr = state->config->tuner_address,
-               .flags = 0,
-               .buf = buf,
-               .len = len + 1
-       };
-
-       dprintk(2, "\n");
-
-       msg.buf[0] = reg;
-       memcpy(msg.buf + 1, data, len);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       ret = i2c_transfer(state->i2c, &msg, 1);
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       if (ret < 0)
-               printk(KERN_ERR "%s error ret=%d\n", __func__, ret);
-
-       return ret;
-}
-
-/*
- * mt2063_write - Write register data into the I2C bus, caching the value
- */
-static u32 mt2063_setreg(struct mt2063_state *state, u8 reg, u8 val)
-{
-       u32 status;
-
-       dprintk(2, "\n");
-
-       if (reg >= MT2063_REG_END_REGS)
-               return -ERANGE;
-
-       status = mt2063_write(state, reg, &val, 1);
-       if (status < 0)
-               return status;
-
-       state->reg[reg] = val;
-
-       return 0;
-}
-
-/*
- * mt2063_read - Read data from the I2C bus
- */
-static u32 mt2063_read(struct mt2063_state *state,
-                          u8 subAddress, u8 *pData, u32 cnt)
-{
-       u32 status = 0; /* Status to be returned        */
-       struct dvb_frontend *fe = state->frontend;
-       u32 i = 0;
-
-       dprintk(2, "addr 0x%02x, cnt %d\n", subAddress, cnt);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       for (i = 0; i < cnt; i++) {
-               u8 b0[] = { subAddress + i };
-               struct i2c_msg msg[] = {
-                       {
-                               .addr = state->config->tuner_address,
-                               .flags = 0,
-                               .buf = b0,
-                               .len = 1
-                       }, {
-                               .addr = state->config->tuner_address,
-                               .flags = I2C_M_RD,
-                               .buf = pData + i,
-                               .len = 1
-                       }
-               };
-
-               status = i2c_transfer(state->i2c, msg, 2);
-               dprintk(2, "addr 0x%02x, ret = %d, val = 0x%02x\n",
-                          subAddress + i, status, *(pData + i));
-               if (status < 0)
-                       break;
-       }
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       if (status < 0)
-               printk(KERN_ERR "Can't read from address 0x%02x,\n",
-                      subAddress + i);
-
-       return status;
-}
-
-/*
- * FIXME: Is this really needed?
- */
-static int MT2063_Sleep(struct dvb_frontend *fe)
-{
-       /*
-        *  ToDo:  Add code here to implement a OS blocking
-        */
-       msleep(100);
-
-       return 0;
-}
-
-/*
- * Microtune spur avoidance
- */
-
-/*  Implement ceiling, floor functions.  */
-#define ceil(n, d) (((n) < 0) ? (-((-(n))/(d))) : (n)/(d) + ((n)%(d) != 0))
-#define floor(n, d) (((n) < 0) ? (-((-(n))/(d))) - ((n)%(d) != 0) : (n)/(d))
-
-struct MT2063_FIFZone_t {
-       s32 min_;
-       s32 max_;
-};
-
-static struct MT2063_ExclZone_t *InsertNode(struct MT2063_AvoidSpursData_t
-                                           *pAS_Info,
-                                           struct MT2063_ExclZone_t *pPrevNode)
-{
-       struct MT2063_ExclZone_t *pNode;
-
-       dprintk(2, "\n");
-
-       /*  Check for a node in the free list  */
-       if (pAS_Info->freeZones != NULL) {
-               /*  Use one from the free list  */
-               pNode = pAS_Info->freeZones;
-               pAS_Info->freeZones = pNode->next_;
-       } else {
-               /*  Grab a node from the array  */
-               pNode = &pAS_Info->MT2063_ExclZones[pAS_Info->nZones];
-       }
-
-       if (pPrevNode != NULL) {
-               pNode->next_ = pPrevNode->next_;
-               pPrevNode->next_ = pNode;
-       } else {                /*  insert at the beginning of the list  */
-
-               pNode->next_ = pAS_Info->usedZones;
-               pAS_Info->usedZones = pNode;
-       }
-
-       pAS_Info->nZones++;
-       return pNode;
-}
-
-static struct MT2063_ExclZone_t *RemoveNode(struct MT2063_AvoidSpursData_t
-                                           *pAS_Info,
-                                           struct MT2063_ExclZone_t *pPrevNode,
-                                           struct MT2063_ExclZone_t
-                                           *pNodeToRemove)
-{
-       struct MT2063_ExclZone_t *pNext = pNodeToRemove->next_;
-
-       dprintk(2, "\n");
-
-       /*  Make previous node point to the subsequent node  */
-       if (pPrevNode != NULL)
-               pPrevNode->next_ = pNext;
-
-       /*  Add pNodeToRemove to the beginning of the freeZones  */
-       pNodeToRemove->next_ = pAS_Info->freeZones;
-       pAS_Info->freeZones = pNodeToRemove;
-
-       /*  Decrement node count  */
-       pAS_Info->nZones--;
-
-       return pNext;
-}
-
-/*
- * MT_AddExclZone()
- *
- * Add (and merge) an exclusion zone into the list.
- * If the range (f_min, f_max) is totally outside the
- * 1st IF BW, ignore the entry.
- * If the range (f_min, f_max) is negative, ignore the entry.
- */
-static void MT2063_AddExclZone(struct MT2063_AvoidSpursData_t *pAS_Info,
-                              u32 f_min, u32 f_max)
-{
-       struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
-       struct MT2063_ExclZone_t *pPrev = NULL;
-       struct MT2063_ExclZone_t *pNext = NULL;
-
-       dprintk(2, "\n");
-
-       /*  Check to see if this overlaps the 1st IF filter  */
-       if ((f_max > (pAS_Info->f_if1_Center - (pAS_Info->f_if1_bw / 2)))
-           && (f_min < (pAS_Info->f_if1_Center + (pAS_Info->f_if1_bw / 2)))
-           && (f_min < f_max)) {
-               /*
-                *                1        2         3      4       5        6
-                *
-                *   New entry:  |---|    |--|      |--|    |-|    |---|    |--|
-                *                or       or        or     or      or
-                *   Existing:  |--|      |--|      |--|    |---|  |-|      |--|
-                */
-
-               /*  Check for our place in the list  */
-               while ((pNode != NULL) && (pNode->max_ < f_min)) {
-                       pPrev = pNode;
-                       pNode = pNode->next_;
-               }
-
-               if ((pNode != NULL) && (pNode->min_ < f_max)) {
-                       /*  Combine me with pNode  */
-                       if (f_min < pNode->min_)
-                               pNode->min_ = f_min;
-                       if (f_max > pNode->max_)
-                               pNode->max_ = f_max;
-               } else {
-                       pNode = InsertNode(pAS_Info, pPrev);
-                       pNode->min_ = f_min;
-                       pNode->max_ = f_max;
-               }
-
-               /*  Look for merging possibilities  */
-               pNext = pNode->next_;
-               while ((pNext != NULL) && (pNext->min_ < pNode->max_)) {
-                       if (pNext->max_ > pNode->max_)
-                               pNode->max_ = pNext->max_;
-                       /*  Remove pNext, return ptr to pNext->next  */
-                       pNext = RemoveNode(pAS_Info, pNode, pNext);
-               }
-       }
-}
-
-/*
- *  Reset all exclusion zones.
- *  Add zones to protect the PLL FracN regions near zero
- */
-static void MT2063_ResetExclZones(struct MT2063_AvoidSpursData_t *pAS_Info)
-{
-       u32 center;
-
-       dprintk(2, "\n");
-
-       pAS_Info->nZones = 0;   /*  this clears the used list  */
-       pAS_Info->usedZones = NULL;     /*  reset ptr                  */
-       pAS_Info->freeZones = NULL;     /*  reset ptr                  */
-
-       center =
-           pAS_Info->f_ref *
-           ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 +
-             pAS_Info->f_in) / pAS_Info->f_ref) - pAS_Info->f_in;
-       while (center <
-              pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
-              pAS_Info->f_LO1_FracN_Avoid) {
-               /*  Exclude LO1 FracN  */
-               MT2063_AddExclZone(pAS_Info,
-                                  center - pAS_Info->f_LO1_FracN_Avoid,
-                                  center - 1);
-               MT2063_AddExclZone(pAS_Info, center + 1,
-                                  center + pAS_Info->f_LO1_FracN_Avoid);
-               center += pAS_Info->f_ref;
-       }
-
-       center =
-           pAS_Info->f_ref *
-           ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 -
-             pAS_Info->f_out) / pAS_Info->f_ref) + pAS_Info->f_out;
-       while (center <
-              pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
-              pAS_Info->f_LO2_FracN_Avoid) {
-               /*  Exclude LO2 FracN  */
-               MT2063_AddExclZone(pAS_Info,
-                                  center - pAS_Info->f_LO2_FracN_Avoid,
-                                  center - 1);
-               MT2063_AddExclZone(pAS_Info, center + 1,
-                                  center + pAS_Info->f_LO2_FracN_Avoid);
-               center += pAS_Info->f_ref;
-       }
-
-       if (MT2063_EXCLUDE_US_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
-               /*  Exclude LO1 values that conflict with DECT channels */
-               MT2063_AddExclZone(pAS_Info, 1920836000 - pAS_Info->f_in, 1922236000 - pAS_Info->f_in); /* Ctr = 1921.536 */
-               MT2063_AddExclZone(pAS_Info, 1922564000 - pAS_Info->f_in, 1923964000 - pAS_Info->f_in); /* Ctr = 1923.264 */
-               MT2063_AddExclZone(pAS_Info, 1924292000 - pAS_Info->f_in, 1925692000 - pAS_Info->f_in); /* Ctr = 1924.992 */
-               MT2063_AddExclZone(pAS_Info, 1926020000 - pAS_Info->f_in, 1927420000 - pAS_Info->f_in); /* Ctr = 1926.720 */
-               MT2063_AddExclZone(pAS_Info, 1927748000 - pAS_Info->f_in, 1929148000 - pAS_Info->f_in); /* Ctr = 1928.448 */
-       }
-
-       if (MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
-               MT2063_AddExclZone(pAS_Info, 1896644000 - pAS_Info->f_in, 1898044000 - pAS_Info->f_in); /* Ctr = 1897.344 */
-               MT2063_AddExclZone(pAS_Info, 1894916000 - pAS_Info->f_in, 1896316000 - pAS_Info->f_in); /* Ctr = 1895.616 */
-               MT2063_AddExclZone(pAS_Info, 1893188000 - pAS_Info->f_in, 1894588000 - pAS_Info->f_in); /* Ctr = 1893.888 */
-               MT2063_AddExclZone(pAS_Info, 1891460000 - pAS_Info->f_in, 1892860000 - pAS_Info->f_in); /* Ctr = 1892.16  */
-               MT2063_AddExclZone(pAS_Info, 1889732000 - pAS_Info->f_in, 1891132000 - pAS_Info->f_in); /* Ctr = 1890.432 */
-               MT2063_AddExclZone(pAS_Info, 1888004000 - pAS_Info->f_in, 1889404000 - pAS_Info->f_in); /* Ctr = 1888.704 */
-               MT2063_AddExclZone(pAS_Info, 1886276000 - pAS_Info->f_in, 1887676000 - pAS_Info->f_in); /* Ctr = 1886.976 */
-               MT2063_AddExclZone(pAS_Info, 1884548000 - pAS_Info->f_in, 1885948000 - pAS_Info->f_in); /* Ctr = 1885.248 */
-               MT2063_AddExclZone(pAS_Info, 1882820000 - pAS_Info->f_in, 1884220000 - pAS_Info->f_in); /* Ctr = 1883.52  */
-               MT2063_AddExclZone(pAS_Info, 1881092000 - pAS_Info->f_in, 1882492000 - pAS_Info->f_in); /* Ctr = 1881.792 */
-       }
-}
-
-/*
- * MT_ChooseFirstIF - Choose the best available 1st IF
- *                    If f_Desired is not excluded, choose that first.
- *                    Otherwise, return the value closest to f_Center that is
- *                    not excluded
- */
-static u32 MT2063_ChooseFirstIF(struct MT2063_AvoidSpursData_t *pAS_Info)
-{
-       /*
-        * Update "f_Desired" to be the nearest "combinational-multiple" of
-        * "f_LO1_Step".
-        * The resulting number, F_LO1 must be a multiple of f_LO1_Step.
-        * And F_LO1 is the arithmetic sum of f_in + f_Center.
-        * Neither f_in, nor f_Center must be a multiple of f_LO1_Step.
-        * However, the sum must be.
-        */
-       const u32 f_Desired =
-           pAS_Info->f_LO1_Step *
-           ((pAS_Info->f_if1_Request + pAS_Info->f_in +
-             pAS_Info->f_LO1_Step / 2) / pAS_Info->f_LO1_Step) -
-           pAS_Info->f_in;
-       const u32 f_Step =
-           (pAS_Info->f_LO1_Step >
-            pAS_Info->f_LO2_Step) ? pAS_Info->f_LO1_Step : pAS_Info->
-           f_LO2_Step;
-       u32 f_Center;
-       s32 i;
-       s32 j = 0;
-       u32 bDesiredExcluded = 0;
-       u32 bZeroExcluded = 0;
-       s32 tmpMin, tmpMax;
-       s32 bestDiff;
-       struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
-       struct MT2063_FIFZone_t zones[MT2063_MAX_ZONES];
-
-       dprintk(2, "\n");
-
-       if (pAS_Info->nZones == 0)
-               return f_Desired;
-
-       /*
-        *  f_Center needs to be an integer multiple of f_Step away
-        *  from f_Desired
-        */
-       if (pAS_Info->f_if1_Center > f_Desired)
-               f_Center =
-                   f_Desired +
-                   f_Step *
-                   ((pAS_Info->f_if1_Center - f_Desired +
-                     f_Step / 2) / f_Step);
-       else
-               f_Center =
-                   f_Desired -
-                   f_Step *
-                   ((f_Desired - pAS_Info->f_if1_Center +
-                     f_Step / 2) / f_Step);
-
-       /*
-        * Take MT_ExclZones, center around f_Center and change the
-        * resolution to f_Step
-        */
-       while (pNode != NULL) {
-               /*  floor function  */
-               tmpMin =
-                   floor((s32) (pNode->min_ - f_Center), (s32) f_Step);
-
-               /*  ceil function  */
-               tmpMax =
-                   ceil((s32) (pNode->max_ - f_Center), (s32) f_Step);
-
-               if ((pNode->min_ < f_Desired) && (pNode->max_ > f_Desired))
-                       bDesiredExcluded = 1;
-
-               if ((tmpMin < 0) && (tmpMax > 0))
-                       bZeroExcluded = 1;
-
-               /*  See if this zone overlaps the previous  */
-               if ((j > 0) && (tmpMin < zones[j - 1].max_))
-                       zones[j - 1].max_ = tmpMax;
-               else {
-                       /*  Add new zone  */
-                       zones[j].min_ = tmpMin;
-                       zones[j].max_ = tmpMax;
-                       j++;
-               }
-               pNode = pNode->next_;
-       }
-
-       /*
-        *  If the desired is okay, return with it
-        */
-       if (bDesiredExcluded == 0)
-               return f_Desired;
-
-       /*
-        *  If the desired is excluded and the center is okay, return with it
-        */
-       if (bZeroExcluded == 0)
-               return f_Center;
-
-       /*  Find the value closest to 0 (f_Center)  */
-       bestDiff = zones[0].min_;
-       for (i = 0; i < j; i++) {
-               if (abs(zones[i].min_) < abs(bestDiff))
-                       bestDiff = zones[i].min_;
-               if (abs(zones[i].max_) < abs(bestDiff))
-                       bestDiff = zones[i].max_;
-       }
-
-       if (bestDiff < 0)
-               return f_Center - ((u32) (-bestDiff) * f_Step);
-
-       return f_Center + (bestDiff * f_Step);
-}
-
-/**
- * gcd() - Uses Euclid's algorithm
- *
- * @u, @v:     Unsigned values whose GCD is desired.
- *
- * Returns THE greatest common divisor of u and v, if either value is 0,
- * the other value is returned as the result.
- */
-static u32 MT2063_gcd(u32 u, u32 v)
-{
-       u32 r;
-
-       while (v != 0) {
-               r = u % v;
-               u = v;
-               v = r;
-       }
-
-       return u;
-}
-
-/**
- * IsSpurInBand() - Checks to see if a spur will be present within the IF's
- *                  bandwidth. (fIFOut +/- fIFBW, -fIFOut +/- fIFBW)
- *
- *                    ma   mb                                     mc   md
- *                  <--+-+-+-------------------+-------------------+-+-+-->
- *                     |   ^                   0                   ^   |
- *                     ^   b=-fIFOut+fIFBW/2      -b=+fIFOut-fIFBW/2   ^
- *                     a=-fIFOut-fIFBW/2              -a=+fIFOut+fIFBW/2
- *
- *                  Note that some equations are doubled to prevent round-off
- *                  problems when calculating fIFBW/2
- *
- * @pAS_Info:  Avoid Spurs information block
- * @fm:                If spur, amount f_IF1 has to move negative
- * @fp:                If spur, amount f_IF1 has to move positive
- *
- *  Returns 1 if an LO spur would be present, otherwise 0.
- */
-static u32 IsSpurInBand(struct MT2063_AvoidSpursData_t *pAS_Info,
-                       u32 *fm, u32 * fp)
-{
-       /*
-        **  Calculate LO frequency settings.
-        */
-       u32 n, n0;
-       const u32 f_LO1 = pAS_Info->f_LO1;
-       const u32 f_LO2 = pAS_Info->f_LO2;
-       const u32 d = pAS_Info->f_out + pAS_Info->f_out_bw / 2;
-       const u32 c = d - pAS_Info->f_out_bw;
-       const u32 f = pAS_Info->f_zif_bw / 2;
-       const u32 f_Scale = (f_LO1 / (UINT_MAX / 2 / pAS_Info->maxH1)) + 1;
-       s32 f_nsLO1, f_nsLO2;
-       s32 f_Spur;
-       u32 ma, mb, mc, md, me, mf;
-       u32 lo_gcd, gd_Scale, gc_Scale, gf_Scale, hgds, hgfs, hgcs;
-
-       dprintk(2, "\n");
-
-       *fm = 0;
-
-       /*
-        ** For each edge (d, c & f), calculate a scale, based on the gcd
-        ** of f_LO1, f_LO2 and the edge value.  Use the larger of this
-        ** gcd-based scale factor or f_Scale.
-        */
-       lo_gcd = MT2063_gcd(f_LO1, f_LO2);
-       gd_Scale = max((u32) MT2063_gcd(lo_gcd, d), f_Scale);
-       hgds = gd_Scale / 2;
-       gc_Scale = max((u32) MT2063_gcd(lo_gcd, c), f_Scale);
-       hgcs = gc_Scale / 2;
-       gf_Scale = max((u32) MT2063_gcd(lo_gcd, f), f_Scale);
-       hgfs = gf_Scale / 2;
-
-       n0 = DIV_ROUND_UP(f_LO2 - d, f_LO1 - f_LO2);
-
-       /*  Check out all multiples of LO1 from n0 to m_maxLOSpurHarmonic  */
-       for (n = n0; n <= pAS_Info->maxH1; ++n) {
-               md = (n * ((f_LO1 + hgds) / gd_Scale) -
-                     ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
-
-               /*  If # fLO2 harmonics > m_maxLOSpurHarmonic, then no spurs present  */
-               if (md >= pAS_Info->maxH1)
-                       break;
-
-               ma = (n * ((f_LO1 + hgds) / gd_Scale) +
-                     ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
-
-               /*  If no spurs between +/- (f_out + f_IFBW/2), then try next harmonic  */
-               if (md == ma)
-                       continue;
-
-               mc = (n * ((f_LO1 + hgcs) / gc_Scale) -
-                     ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
-               if (mc != md) {
-                       f_nsLO1 = (s32) (n * (f_LO1 / gc_Scale));
-                       f_nsLO2 = (s32) (mc * (f_LO2 / gc_Scale));
-                       f_Spur =
-                           (gc_Scale * (f_nsLO1 - f_nsLO2)) +
-                           n * (f_LO1 % gc_Scale) - mc * (f_LO2 % gc_Scale);
-
-                       *fp = ((f_Spur - (s32) c) / (mc - n)) + 1;
-                       *fm = (((s32) d - f_Spur) / (mc - n)) + 1;
-                       return 1;
-               }
-
-               /*  Location of Zero-IF-spur to be checked  */
-               me = (n * ((f_LO1 + hgfs) / gf_Scale) +
-                     ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
-               mf = (n * ((f_LO1 + hgfs) / gf_Scale) -
-                     ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
-               if (me != mf) {
-                       f_nsLO1 = n * (f_LO1 / gf_Scale);
-                       f_nsLO2 = me * (f_LO2 / gf_Scale);
-                       f_Spur =
-                           (gf_Scale * (f_nsLO1 - f_nsLO2)) +
-                           n * (f_LO1 % gf_Scale) - me * (f_LO2 % gf_Scale);
-
-                       *fp = ((f_Spur + (s32) f) / (me - n)) + 1;
-                       *fm = (((s32) f - f_Spur) / (me - n)) + 1;
-                       return 1;
-               }
-
-               mb = (n * ((f_LO1 + hgcs) / gc_Scale) +
-                     ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
-               if (ma != mb) {
-                       f_nsLO1 = n * (f_LO1 / gc_Scale);
-                       f_nsLO2 = ma * (f_LO2 / gc_Scale);
-                       f_Spur =
-                           (gc_Scale * (f_nsLO1 - f_nsLO2)) +
-                           n * (f_LO1 % gc_Scale) - ma * (f_LO2 % gc_Scale);
-
-                       *fp = (((s32) d + f_Spur) / (ma - n)) + 1;
-                       *fm = (-(f_Spur + (s32) c) / (ma - n)) + 1;
-                       return 1;
-               }
-       }
-
-       /*  No spurs found  */
-       return 0;
-}
-
-/*
- * MT_AvoidSpurs() - Main entry point to avoid spurs.
- *                   Checks for existing spurs in present LO1, LO2 freqs
- *                   and if present, chooses spur-free LO1, LO2 combination
- *                   that tunes the same input/output frequencies.
- */
-static u32 MT2063_AvoidSpurs(struct MT2063_AvoidSpursData_t *pAS_Info)
-{
-       u32 status = 0;
-       u32 fm, fp;             /*  restricted range on LO's        */
-       pAS_Info->bSpurAvoided = 0;
-       pAS_Info->nSpursFound = 0;
-
-       dprintk(2, "\n");
-
-       if (pAS_Info->maxH1 == 0)
-               return 0;
-
-       /*
-        * Avoid LO Generated Spurs
-        *
-        * Make sure that have no LO-related spurs within the IF output
-        * bandwidth.
-        *
-        * If there is an LO spur in this band, start at the current IF1 frequency
-        * and work out until we find a spur-free frequency or run up against the
-        * 1st IF SAW band edge.  Use temporary copies of fLO1 and fLO2 so that they
-        * will be unchanged if a spur-free setting is not found.
-        */
-       pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
-       if (pAS_Info->bSpurPresent) {
-               u32 zfIF1 = pAS_Info->f_LO1 - pAS_Info->f_in;   /*  current attempt at a 1st IF  */
-               u32 zfLO1 = pAS_Info->f_LO1;    /*  current attempt at an LO1 freq  */
-               u32 zfLO2 = pAS_Info->f_LO2;    /*  current attempt at an LO2 freq  */
-               u32 delta_IF1;
-               u32 new_IF1;
-
-               /*
-                **  Spur was found, attempt to find a spur-free 1st IF
-                */
-               do {
-                       pAS_Info->nSpursFound++;
-
-                       /*  Raise f_IF1_upper, if needed  */
-                       MT2063_AddExclZone(pAS_Info, zfIF1 - fm, zfIF1 + fp);
-
-                       /*  Choose next IF1 that is closest to f_IF1_CENTER              */
-                       new_IF1 = MT2063_ChooseFirstIF(pAS_Info);
-
-                       if (new_IF1 > zfIF1) {
-                               pAS_Info->f_LO1 += (new_IF1 - zfIF1);
-                               pAS_Info->f_LO2 += (new_IF1 - zfIF1);
-                       } else {
-                               pAS_Info->f_LO1 -= (zfIF1 - new_IF1);
-                               pAS_Info->f_LO2 -= (zfIF1 - new_IF1);
-                       }
-                       zfIF1 = new_IF1;
-
-                       if (zfIF1 > pAS_Info->f_if1_Center)
-                               delta_IF1 = zfIF1 - pAS_Info->f_if1_Center;
-                       else
-                               delta_IF1 = pAS_Info->f_if1_Center - zfIF1;
-
-                       pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
-               /*
-                *  Continue while the new 1st IF is still within the 1st IF bandwidth
-                *  and there is a spur in the band (again)
-                */
-               } while ((2 * delta_IF1 + pAS_Info->f_out_bw <= pAS_Info->f_if1_bw) && pAS_Info->bSpurPresent);
-
-               /*
-                * Use the LO-spur free values found.  If the search went all
-                * the way to the 1st IF band edge and always found spurs, just
-                * leave the original choice.  It's as "good" as any other.
-                */
-               if (pAS_Info->bSpurPresent == 1) {
-                       status |= MT2063_SPUR_PRESENT_ERR;
-                       pAS_Info->f_LO1 = zfLO1;
-                       pAS_Info->f_LO2 = zfLO2;
-               } else
-                       pAS_Info->bSpurAvoided = 1;
-       }
-
-       status |=
-           ((pAS_Info->
-             nSpursFound << MT2063_SPUR_SHIFT) & MT2063_SPUR_CNT_MASK);
-
-       return status;
-}
-
-/*
- * Constants used by the tuning algorithm
- */
-#define MT2063_REF_FREQ          (16000000UL)  /* Reference oscillator Frequency (in Hz) */
-#define MT2063_IF1_BW            (22000000UL)  /* The IF1 filter bandwidth (in Hz) */
-#define MT2063_TUNE_STEP_SIZE       (50000UL)  /* Tune in steps of 50 kHz */
-#define MT2063_SPUR_STEP_HZ        (250000UL)  /* Step size (in Hz) to move IF1 when avoiding spurs */
-#define MT2063_ZIF_BW             (2000000UL)  /* Zero-IF spur-free bandwidth (in Hz) */
-#define MT2063_MAX_HARMONICS_1         (15UL)  /* Highest intra-tuner LO Spur Harmonic to be avoided */
-#define MT2063_MAX_HARMONICS_2          (5UL)  /* Highest inter-tuner LO Spur Harmonic to be avoided */
-#define MT2063_MIN_LO_SEP         (1000000UL)  /* Minimum inter-tuner LO frequency separation */
-#define MT2063_LO1_FRACN_AVOID          (0UL)  /* LO1 FracN numerator avoid region (in Hz) */
-#define MT2063_LO2_FRACN_AVOID     (199999UL)  /* LO2 FracN numerator avoid region (in Hz) */
-#define MT2063_MIN_FIN_FREQ      (44000000UL)  /* Minimum input frequency (in Hz) */
-#define MT2063_MAX_FIN_FREQ    (1100000000UL)  /* Maximum input frequency (in Hz) */
-#define MT2063_MIN_FOUT_FREQ     (36000000UL)  /* Minimum output frequency (in Hz) */
-#define MT2063_MAX_FOUT_FREQ     (57000000UL)  /* Maximum output frequency (in Hz) */
-#define MT2063_MIN_DNC_FREQ    (1293000000UL)  /* Minimum LO2 frequency (in Hz) */
-#define MT2063_MAX_DNC_FREQ    (1614000000UL)  /* Maximum LO2 frequency (in Hz) */
-#define MT2063_MIN_UPC_FREQ    (1396000000UL)  /* Minimum LO1 frequency (in Hz) */
-#define MT2063_MAX_UPC_FREQ    (2750000000UL)  /* Maximum LO1 frequency (in Hz) */
-
-/*
- *  Define the supported Part/Rev codes for the MT2063
- */
-#define MT2063_B0       (0x9B)
-#define MT2063_B1       (0x9C)
-#define MT2063_B2       (0x9D)
-#define MT2063_B3       (0x9E)
-
-/**
- * mt2063_lockStatus - Checks to see if LO1 and LO2 are locked
- *
- * @state:     struct mt2063_state pointer
- *
- * This function returns 0, if no lock, 1 if locked and a value < 1 if error
- */
-static unsigned int mt2063_lockStatus(struct mt2063_state *state)
-{
-       const u32 nMaxWait = 100;       /*  wait a maximum of 100 msec   */
-       const u32 nPollRate = 2;        /*  poll status bits every 2 ms */
-       const u32 nMaxLoops = nMaxWait / nPollRate;
-       const u8 LO1LK = 0x80;
-       u8 LO2LK = 0x08;
-       u32 status;
-       u32 nDelays = 0;
-
-       dprintk(2, "\n");
-
-       /*  LO2 Lock bit was in a different place for B0 version  */
-       if (state->tuner_id == MT2063_B0)
-               LO2LK = 0x40;
-
-       do {
-               status = mt2063_read(state, MT2063_REG_LO_STATUS,
-                                    &state->reg[MT2063_REG_LO_STATUS], 1);
-
-               if (status < 0)
-                       return status;
-
-               if ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) ==
-                   (LO1LK | LO2LK)) {
-                       return TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO;
-               }
-               msleep(nPollRate);      /*  Wait between retries  */
-       } while (++nDelays < nMaxLoops);
-
-       /*
-        * Got no lock or partial lock
-        */
-       return 0;
-}
-
-/*
- *  Constants for setting receiver modes.
- *  (6 modes defined at this time, enumerated by mt2063_delivery_sys)
- *  (DNC1GC & DNC2GC are the values, which are used, when the specific
- *   DNC Output is selected, the other is always off)
- *
- *                enum mt2063_delivery_sys
- * -------------+----------------------------------------------
- * Mode 0 :     | MT2063_CABLE_QAM
- * Mode 1 :     | MT2063_CABLE_ANALOG
- * Mode 2 :     | MT2063_OFFAIR_COFDM
- * Mode 3 :     | MT2063_OFFAIR_COFDM_SAWLESS
- * Mode 4 :     | MT2063_OFFAIR_ANALOG
- * Mode 5 :     | MT2063_OFFAIR_8VSB
- * --------------+----------------------------------------------
- *
- *                |<----------   Mode  -------------->|
- *    Reg Field   |  0  |  1  |  2  |  3  |  4  |  5  |
- *    ------------+-----+-----+-----+-----+-----+-----+
- *    RFAGCen     | OFF | OFF | OFF | OFF | OFF | OFF
- *    LNARin      |   0 |   0 |   3 |   3 |  3  |  3
- *    FIFFQen     |   1 |   1 |   1 |   1 |  1  |  1
- *    FIFFq       |   0 |   0 |   0 |   0 |  0  |  0
- *    DNC1gc      |   0 |   0 |   0 |   0 |  0  |  0
- *    DNC2gc      |   0 |   0 |   0 |   0 |  0  |  0
- *    GCU Auto    |   1 |   1 |   1 |   1 |  1  |  1
- *    LNA max Atn |  31 |  31 |  31 |  31 | 31  | 31
- *    LNA Target  |  44 |  43 |  43 |  43 | 43  | 43
- *    ign  RF Ovl |   0 |   0 |   0 |   0 |  0  |  0
- *    RF  max Atn |  31 |  31 |  31 |  31 | 31  | 31
- *    PD1 Target  |  36 |  36 |  38 |  38 | 36  | 38
- *    ign FIF Ovl |   0 |   0 |   0 |   0 |  0  |  0
- *    FIF max Atn |   5 |   5 |   5 |   5 |  5  |  5
- *    PD2 Target  |  40 |  33 |  42 |  42 | 33  | 42
- */
-
-enum mt2063_delivery_sys {
-       MT2063_CABLE_QAM = 0,
-       MT2063_CABLE_ANALOG,
-       MT2063_OFFAIR_COFDM,
-       MT2063_OFFAIR_COFDM_SAWLESS,
-       MT2063_OFFAIR_ANALOG,
-       MT2063_OFFAIR_8VSB,
-       MT2063_NUM_RCVR_MODES
-};
-
-static const char *mt2063_mode_name[] = {
-       [MT2063_CABLE_QAM]              = "digital cable",
-       [MT2063_CABLE_ANALOG]           = "analog cable",
-       [MT2063_OFFAIR_COFDM]           = "digital offair",
-       [MT2063_OFFAIR_COFDM_SAWLESS]   = "digital offair without SAW",
-       [MT2063_OFFAIR_ANALOG]          = "analog offair",
-       [MT2063_OFFAIR_8VSB]            = "analog offair 8vsb",
-};
-
-static const u8 RFAGCEN[]      = {  0,  0,  0,  0,  0,  0 };
-static const u8 LNARIN[]       = {  0,  0,  3,  3,  3,  3 };
-static const u8 FIFFQEN[]      = {  1,  1,  1,  1,  1,  1 };
-static const u8 FIFFQ[]                = {  0,  0,  0,  0,  0,  0 };
-static const u8 DNC1GC[]       = {  0,  0,  0,  0,  0,  0 };
-static const u8 DNC2GC[]       = {  0,  0,  0,  0,  0,  0 };
-static const u8 ACLNAMAX[]     = { 31, 31, 31, 31, 31, 31 };
-static const u8 LNATGT[]       = { 44, 43, 43, 43, 43, 43 };
-static const u8 RFOVDIS[]      = {  0,  0,  0,  0,  0,  0 };
-static const u8 ACRFMAX[]      = { 31, 31, 31, 31, 31, 31 };
-static const u8 PD1TGT[]       = { 36, 36, 38, 38, 36, 38 };
-static const u8 FIFOVDIS[]     = {  0,  0,  0,  0,  0,  0 };
-static const u8 ACFIFMAX[]     = { 29, 29, 29, 29, 29, 29 };
-static const u8 PD2TGT[]       = { 40, 33, 38, 42, 30, 38 };
-
-/*
- * mt2063_set_dnc_output_enable()
- */
-static u32 mt2063_get_dnc_output_enable(struct mt2063_state *state,
-                                       enum MT2063_DNC_Output_Enable *pValue)
-{
-       dprintk(2, "\n");
-
-       if ((state->reg[MT2063_REG_DNC_GAIN] & 0x03) == 0x03) { /* if DNC1 is off */
-               if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03)   /* if DNC2 is off */
-                       *pValue = MT2063_DNC_NONE;
-               else
-                       *pValue = MT2063_DNC_2;
-       } else {        /* DNC1 is on */
-               if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03)   /* if DNC2 is off */
-                       *pValue = MT2063_DNC_1;
-               else
-                       *pValue = MT2063_DNC_BOTH;
-       }
-       return 0;
-}
-
-/*
- * mt2063_set_dnc_output_enable()
- */
-static u32 mt2063_set_dnc_output_enable(struct mt2063_state *state,
-                                       enum MT2063_DNC_Output_Enable nValue)
-{
-       u32 status = 0; /* Status to be returned        */
-       u8 val = 0;
-
-       dprintk(2, "\n");
-
-       /* selects, which DNC output is used */
-       switch (nValue) {
-       case MT2063_DNC_NONE:
-               val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03;  /* Set DNC1GC=3 */
-               if (state->reg[MT2063_REG_DNC_GAIN] !=
-                   val)
-                       status |=
-                           mt2063_setreg(state,
-                                         MT2063_REG_DNC_GAIN,
-                                         val);
-
-               val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03;  /* Set DNC2GC=3 */
-               if (state->reg[MT2063_REG_VGA_GAIN] !=
-                   val)
-                       status |=
-                           mt2063_setreg(state,
-                                         MT2063_REG_VGA_GAIN,
-                                         val);
-
-               val = (state->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */
-               if (state->reg[MT2063_REG_RSVD_20] !=
-                   val)
-                       status |=
-                           mt2063_setreg(state,
-                                         MT2063_REG_RSVD_20,
-                                         val);
-
-               break;
-       case MT2063_DNC_1:
-               val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03);     /* Set DNC1GC=x */
-               if (state->reg[MT2063_REG_DNC_GAIN] !=
-                   val)
-                       status |=
-                           mt2063_setreg(state,
-                                         MT2063_REG_DNC_GAIN,
-                                         val);
-
-               val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03;  /* Set DNC2GC=3 */
-               if (state->reg[MT2063_REG_VGA_GAIN] !=
-                   val)
-                       status |=
-                           mt2063_setreg(state,
-                                         MT2063_REG_VGA_GAIN,
-                                         val);
-
-               val = (state->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */
-               if (state->reg[MT2063_REG_RSVD_20] !=
-                   val)
-                       status |=
-                           mt2063_setreg(state,
-                                         MT2063_REG_RSVD_20,
-                                         val);
-
-               break;
-       case MT2063_DNC_2:
-               val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03;  /* Set DNC1GC=3 */
-               if (state->reg[MT2063_REG_DNC_GAIN] !=
-                   val)
-                       status |=
-                           mt2063_setreg(state,
-                                         MT2063_REG_DNC_GAIN,
-                                         val);
-
-               val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03);     /* Set DNC2GC=x */
-               if (state->reg[MT2063_REG_VGA_GAIN] !=
-                   val)
-                       status |=
-                           mt2063_setreg(state,
-                                         MT2063_REG_VGA_GAIN,
-                                         val);
-
-               val = (state->reg[MT2063_REG_RSVD_20] | 0x40);  /* Set PD2MUX=1 */
-               if (state->reg[MT2063_REG_RSVD_20] !=
-                   val)
-                       status |=
-                           mt2063_setreg(state,
-                                         MT2063_REG_RSVD_20,
-                                         val);
-
-               break;
-       case MT2063_DNC_BOTH:
-               val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03);     /* Set DNC1GC=x */
-               if (state->reg[MT2063_REG_DNC_GAIN] !=
-                   val)
-                       status |=
-                           mt2063_setreg(state,
-                                         MT2063_REG_DNC_GAIN,
-                                         val);
-
-               val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03);     /* Set DNC2GC=x */
-               if (state->reg[MT2063_REG_VGA_GAIN] !=
-                   val)
-                       status |=
-                           mt2063_setreg(state,
-                                         MT2063_REG_VGA_GAIN,
-                                         val);
-
-               val = (state->reg[MT2063_REG_RSVD_20] | 0x40);  /* Set PD2MUX=1 */
-               if (state->reg[MT2063_REG_RSVD_20] !=
-                   val)
-                       status |=
-                           mt2063_setreg(state,
-                                         MT2063_REG_RSVD_20,
-                                         val);
-
-               break;
-       default:
-               break;
-       }
-
-       return status;
-}
-
-/*
- * MT2063_SetReceiverMode() - Set the MT2063 receiver mode, according with
- *                           the selected enum mt2063_delivery_sys type.
- *
- *  (DNC1GC & DNC2GC are the values, which are used, when the specific
- *   DNC Output is selected, the other is always off)
- *
- * @state:     ptr to mt2063_state structure
- * @Mode:      desired reciever delivery system
- *
- * Note: Register cache must be valid for it to work
- */
-
-static u32 MT2063_SetReceiverMode(struct mt2063_state *state,
-                                 enum mt2063_delivery_sys Mode)
-{
-       u32 status = 0; /* Status to be returned        */
-       u8 val;
-       u32 longval;
-
-       dprintk(2, "\n");
-
-       if (Mode >= MT2063_NUM_RCVR_MODES)
-               status = -ERANGE;
-
-       /* RFAGCen */
-       if (status >= 0) {
-               val =
-                   (state->
-                    reg[MT2063_REG_PD1_TGT] & (u8) ~0x40) | (RFAGCEN[Mode]
-                                                                  ? 0x40 :
-                                                                  0x00);
-               if (state->reg[MT2063_REG_PD1_TGT] != val)
-                       status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
-       }
-
-       /* LNARin */
-       if (status >= 0) {
-               u8 val = (state->reg[MT2063_REG_CTRL_2C] & (u8) ~0x03) |
-                        (LNARIN[Mode] & 0x03);
-               if (state->reg[MT2063_REG_CTRL_2C] != val)
-                       status |= mt2063_setreg(state, MT2063_REG_CTRL_2C, val);
-       }
-
-       /* FIFFQEN and FIFFQ */
-       if (status >= 0) {
-               val =
-                   (state->
-                    reg[MT2063_REG_FIFF_CTRL2] & (u8) ~0xF0) |
-                   (FIFFQEN[Mode] << 7) | (FIFFQ[Mode] << 4);
-               if (state->reg[MT2063_REG_FIFF_CTRL2] != val) {
-                       status |=
-                           mt2063_setreg(state, MT2063_REG_FIFF_CTRL2, val);
-                       /* trigger FIFF calibration, needed after changing FIFFQ */
-                       val =
-                           (state->reg[MT2063_REG_FIFF_CTRL] | (u8) 0x01);
-                       status |=
-                           mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
-                       val =
-                           (state->
-                            reg[MT2063_REG_FIFF_CTRL] & (u8) ~0x01);
-                       status |=
-                           mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
-               }
-       }
-
-       /* DNC1GC & DNC2GC */
-       status |= mt2063_get_dnc_output_enable(state, &longval);
-       status |= mt2063_set_dnc_output_enable(state, longval);
-
-       /* acLNAmax */
-       if (status >= 0) {
-               u8 val = (state->reg[MT2063_REG_LNA_OV] & (u8) ~0x1F) |
-                        (ACLNAMAX[Mode] & 0x1F);
-               if (state->reg[MT2063_REG_LNA_OV] != val)
-                       status |= mt2063_setreg(state, MT2063_REG_LNA_OV, val);
-       }
-
-       /* LNATGT */
-       if (status >= 0) {
-               u8 val = (state->reg[MT2063_REG_LNA_TGT] & (u8) ~0x3F) |
-                        (LNATGT[Mode] & 0x3F);
-               if (state->reg[MT2063_REG_LNA_TGT] != val)
-                       status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
-       }
-
-       /* ACRF */
-       if (status >= 0) {
-               u8 val = (state->reg[MT2063_REG_RF_OV] & (u8) ~0x1F) |
-                        (ACRFMAX[Mode] & 0x1F);
-               if (state->reg[MT2063_REG_RF_OV] != val)
-                       status |= mt2063_setreg(state, MT2063_REG_RF_OV, val);
-       }
-
-       /* PD1TGT */
-       if (status >= 0) {
-               u8 val = (state->reg[MT2063_REG_PD1_TGT] & (u8) ~0x3F) |
-                        (PD1TGT[Mode] & 0x3F);
-               if (state->reg[MT2063_REG_PD1_TGT] != val)
-                       status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
-       }
-
-       /* FIFATN */
-       if (status >= 0) {
-               u8 val = ACFIFMAX[Mode];
-               if (state->reg[MT2063_REG_PART_REV] != MT2063_B3 && val > 5)
-                       val = 5;
-               val = (state->reg[MT2063_REG_FIF_OV] & (u8) ~0x1F) |
-                     (val & 0x1F);
-               if (state->reg[MT2063_REG_FIF_OV] != val)
-                       status |= mt2063_setreg(state, MT2063_REG_FIF_OV, val);
-       }
-
-       /* PD2TGT */
-       if (status >= 0) {
-               u8 val = (state->reg[MT2063_REG_PD2_TGT] & (u8) ~0x3F) |
-                   (PD2TGT[Mode] & 0x3F);
-               if (state->reg[MT2063_REG_PD2_TGT] != val)
-                       status |= mt2063_setreg(state, MT2063_REG_PD2_TGT, val);
-       }
-
-       /* Ignore ATN Overload */
-       if (status >= 0) {
-               val = (state->reg[MT2063_REG_LNA_TGT] & (u8) ~0x80) |
-                     (RFOVDIS[Mode] ? 0x80 : 0x00);
-               if (state->reg[MT2063_REG_LNA_TGT] != val)
-                       status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
-       }
-
-       /* Ignore FIF Overload */
-       if (status >= 0) {
-               val = (state->reg[MT2063_REG_PD1_TGT] & (u8) ~0x80) |
-                     (FIFOVDIS[Mode] ? 0x80 : 0x00);
-               if (state->reg[MT2063_REG_PD1_TGT] != val)
-                       status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
-       }
-
-       if (status >= 0) {
-               state->rcvr_mode = Mode;
-               dprintk(1, "mt2063 mode changed to %s\n",
-                       mt2063_mode_name[state->rcvr_mode]);
-       }
-
-       return status;
-}
-
-/*
- * MT2063_ClearPowerMaskBits () - Clears the power-down mask bits for various
- *                               sections of the MT2063
- *
- * @Bits:              Mask bits to be cleared.
- *
- * See definition of MT2063_Mask_Bits type for description
- * of each of the power bits.
- */
-static u32 MT2063_ClearPowerMaskBits(struct mt2063_state *state,
-                                    enum MT2063_Mask_Bits Bits)
-{
-       u32 status = 0;
-
-       dprintk(2, "\n");
-       Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD);   /* Only valid bits for this tuner */
-       if ((Bits & 0xFF00) != 0) {
-               state->reg[MT2063_REG_PWR_2] &= ~(u8) (Bits >> 8);
-               status |=
-                   mt2063_write(state,
-                                   MT2063_REG_PWR_2,
-                                   &state->reg[MT2063_REG_PWR_2], 1);
-       }
-       if ((Bits & 0xFF) != 0) {
-               state->reg[MT2063_REG_PWR_1] &= ~(u8) (Bits & 0xFF);
-               status |=
-                   mt2063_write(state,
-                                   MT2063_REG_PWR_1,
-                                   &state->reg[MT2063_REG_PWR_1], 1);
-       }
-
-       return status;
-}
-
-/*
- * MT2063_SoftwareShutdown() - Enables or disables software shutdown function.
- *                            When Shutdown is 1, any section whose power
- *                            mask is set will be shutdown.
- */
-static u32 MT2063_SoftwareShutdown(struct mt2063_state *state, u8 Shutdown)
-{
-       u32 status;
-
-       dprintk(2, "\n");
-       if (Shutdown == 1)
-               state->reg[MT2063_REG_PWR_1] |= 0x04;
-       else
-               state->reg[MT2063_REG_PWR_1] &= ~0x04;
-
-       status = mt2063_write(state,
-                           MT2063_REG_PWR_1,
-                           &state->reg[MT2063_REG_PWR_1], 1);
-
-       if (Shutdown != 1) {
-               state->reg[MT2063_REG_BYP_CTRL] =
-                   (state->reg[MT2063_REG_BYP_CTRL] & 0x9F) | 0x40;
-               status |=
-                   mt2063_write(state,
-                                   MT2063_REG_BYP_CTRL,
-                                   &state->reg[MT2063_REG_BYP_CTRL],
-                                   1);
-               state->reg[MT2063_REG_BYP_CTRL] =
-                   (state->reg[MT2063_REG_BYP_CTRL] & 0x9F);
-               status |=
-                   mt2063_write(state,
-                                   MT2063_REG_BYP_CTRL,
-                                   &state->reg[MT2063_REG_BYP_CTRL],
-                                   1);
-       }
-
-       return status;
-}
-
-static u32 MT2063_Round_fLO(u32 f_LO, u32 f_LO_Step, u32 f_ref)
-{
-       return f_ref * (f_LO / f_ref)
-           + f_LO_Step * (((f_LO % f_ref) + (f_LO_Step / 2)) / f_LO_Step);
-}
-
-/**
- * fLO_FractionalTerm() - Calculates the portion contributed by FracN / denom.
- *                        This function preserves maximum precision without
- *                        risk of overflow.  It accurately calculates
- *                        f_ref * num / denom to within 1 HZ with fixed math.
- *
- * @num :      Fractional portion of the multiplier
- * @denom:     denominator portion of the ratio
- * @f_Ref:     SRO frequency.
- *
- * This calculation handles f_ref as two separate 14-bit fields.
- * Therefore, a maximum value of 2^28-1 may safely be used for f_ref.
- * This is the genesis of the magic number "14" and the magic mask value of
- * 0x03FFF.
- *
- * This routine successfully handles denom values up to and including 2^18.
- *  Returns:        f_ref * num / denom
- */
-static u32 MT2063_fLO_FractionalTerm(u32 f_ref, u32 num, u32 denom)
-{
-       u32 t1 = (f_ref >> 14) * num;
-       u32 term1 = t1 / denom;
-       u32 loss = t1 % denom;
-       u32 term2 =
-           (((f_ref & 0x00003FFF) * num + (loss << 14)) + (denom / 2)) / denom;
-       return (term1 << 14) + term2;
-}
-
-/*
- * CalcLO1Mult()- Calculates Integer divider value and the numerator
- *                value for a FracN PLL.
- *
- *                This function assumes that the f_LO and f_Ref are
- *                evenly divisible by f_LO_Step.
- *
- * @Div:       OUTPUT: Whole number portion of the multiplier
- * @FracN:     OUTPUT: Fractional portion of the multiplier
- * @f_LO:      desired LO frequency.
- * @f_LO_Step: Minimum step size for the LO (in Hz).
- * @f_Ref:     SRO frequency.
- * @f_Avoid:   Range of PLL frequencies to avoid near integer multiples
- *             of f_Ref (in Hz).
- *
- * Returns:        Recalculated LO frequency.
- */
-static u32 MT2063_CalcLO1Mult(u32 *Div,
-                             u32 *FracN,
-                             u32 f_LO,
-                             u32 f_LO_Step, u32 f_Ref)
-{
-       /*  Calculate the whole number portion of the divider */
-       *Div = f_LO / f_Ref;
-
-       /*  Calculate the numerator value (round to nearest f_LO_Step) */
-       *FracN =
-           (64 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
-            (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
-
-       return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN, 64);
-}
-
-/**
- * CalcLO2Mult() - Calculates Integer divider value and the numerator
- *                 value for a FracN PLL.
- *
- *                  This function assumes that the f_LO and f_Ref are
- *                  evenly divisible by f_LO_Step.
- *
- * @Div:       OUTPUT: Whole number portion of the multiplier
- * @FracN:     OUTPUT: Fractional portion of the multiplier
- * @f_LO:      desired LO frequency.
- * @f_LO_Step: Minimum step size for the LO (in Hz).
- * @f_Ref:     SRO frequency.
- * @f_Avoid:   Range of PLL frequencies to avoid near
- *             integer multiples of f_Ref (in Hz).
- *
- * Returns: Recalculated LO frequency.
- */
-static u32 MT2063_CalcLO2Mult(u32 *Div,
-                             u32 *FracN,
-                             u32 f_LO,
-                             u32 f_LO_Step, u32 f_Ref)
-{
-       /*  Calculate the whole number portion of the divider */
-       *Div = f_LO / f_Ref;
-
-       /*  Calculate the numerator value (round to nearest f_LO_Step) */
-       *FracN =
-           (8191 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
-            (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
-
-       return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN,
-                                                           8191);
-}
-
-/*
- * FindClearTuneFilter() - Calculate the corrrect ClearTune filter to be
- *                        used for a given input frequency.
- *
- * @state:     ptr to tuner data structure
- * @f_in:      RF input center frequency (in Hz).
- *
- * Returns: ClearTune filter number (0-31)
- */
-static u32 FindClearTuneFilter(struct mt2063_state *state, u32 f_in)
-{
-       u32 RFBand;
-       u32 idx;                /*  index loop                      */
-
-       /*
-        **  Find RF Band setting
-        */
-       RFBand = 31;            /*  def when f_in > all    */
-       for (idx = 0; idx < 31; ++idx) {
-               if (state->CTFiltMax[idx] >= f_in) {
-                       RFBand = idx;
-                       break;
-               }
-       }
-       return RFBand;
-}
-
-/*
- * MT2063_Tune() - Change the tuner's tuned frequency to RFin.
- */
-static u32 MT2063_Tune(struct mt2063_state *state, u32 f_in)
-{                              /* RF input center frequency   */
-
-       u32 status = 0;
-       u32 LO1;                /*  1st LO register value           */
-       u32 Num1;               /*  Numerator for LO1 reg. value    */
-       u32 f_IF1;              /*  1st IF requested                */
-       u32 LO2;                /*  2nd LO register value           */
-       u32 Num2;               /*  Numerator for LO2 reg. value    */
-       u32 ofLO1, ofLO2;       /*  last time's LO frequencies      */
-       u8 fiffc = 0x80;        /*  FIFF center freq from tuner     */
-       u32 fiffof;             /*  Offset from FIFF center freq    */
-       const u8 LO1LK = 0x80;  /*  Mask for LO1 Lock bit           */
-       u8 LO2LK = 0x08;        /*  Mask for LO2 Lock bit           */
-       u8 val;
-       u32 RFBand;
-
-       dprintk(2, "\n");
-       /*  Check the input and output frequency ranges                   */
-       if ((f_in < MT2063_MIN_FIN_FREQ) || (f_in > MT2063_MAX_FIN_FREQ))
-               return -EINVAL;
-
-       if ((state->AS_Data.f_out < MT2063_MIN_FOUT_FREQ)
-           || (state->AS_Data.f_out > MT2063_MAX_FOUT_FREQ))
-               return -EINVAL;
-
-       /*
-        * Save original LO1 and LO2 register values
-        */
-       ofLO1 = state->AS_Data.f_LO1;
-       ofLO2 = state->AS_Data.f_LO2; 
-
-       /*
-        * Find and set RF Band setting
-        */
-       if (state->ctfilt_sw == 1) {
-               val = (state->reg[MT2063_REG_CTUNE_CTRL] | 0x08);
-               if (state->reg[MT2063_REG_CTUNE_CTRL] != val) {
-                       status |=
-                           mt2063_setreg(state, MT2063_REG_CTUNE_CTRL, val);
-               }
-               val = state->reg[MT2063_REG_CTUNE_OV];
-               RFBand = FindClearTuneFilter(state, f_in);
-               state->reg[MT2063_REG_CTUNE_OV] =
-                   (u8) ((state->reg[MT2063_REG_CTUNE_OV] & ~0x1F)
-                             | RFBand);
-               if (state->reg[MT2063_REG_CTUNE_OV] != val) {
-                       status |=
-                           mt2063_setreg(state, MT2063_REG_CTUNE_OV, val);
-               }
-       }
-
-       /*
-        * Read the FIFF Center Frequency from the tuner
-        */
-       if (status >= 0) {
-               status |=
-                   mt2063_read(state,
-                                  MT2063_REG_FIFFC,
-                                  &state->reg[MT2063_REG_FIFFC], 1);
-               fiffc = state->reg[MT2063_REG_FIFFC];
-       }
-       /*
-        * Assign in the requested values
-        */
-       state->AS_Data.f_in = f_in;
-       /*  Request a 1st IF such that LO1 is on a step size */
-       state->AS_Data.f_if1_Request =
-           MT2063_Round_fLO(state->AS_Data.f_if1_Request + f_in,
-                            state->AS_Data.f_LO1_Step,
-                            state->AS_Data.f_ref) - f_in;
-
-       /*
-        * Calculate frequency settings.  f_IF1_FREQ + f_in is the
-        * desired LO1 frequency
-        */
-       MT2063_ResetExclZones(&state->AS_Data);
-
-       f_IF1 = MT2063_ChooseFirstIF(&state->AS_Data);
-
-       state->AS_Data.f_LO1 =
-           MT2063_Round_fLO(f_IF1 + f_in, state->AS_Data.f_LO1_Step,
-                            state->AS_Data.f_ref);
-
-       state->AS_Data.f_LO2 =
-           MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
-                            state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
-
-       /*
-        * Check for any LO spurs in the output bandwidth and adjust
-        * the LO settings to avoid them if needed
-        */
-       status |= MT2063_AvoidSpurs(&state->AS_Data);
-       /*
-        * MT_AvoidSpurs spurs may have changed the LO1 & LO2 values.
-        * Recalculate the LO frequencies and the values to be placed
-        * in the tuning registers.
-        */
-       state->AS_Data.f_LO1 =
-           MT2063_CalcLO1Mult(&LO1, &Num1, state->AS_Data.f_LO1,
-                              state->AS_Data.f_LO1_Step, state->AS_Data.f_ref);
-       state->AS_Data.f_LO2 =
-           MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
-                            state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
-       state->AS_Data.f_LO2 =
-           MT2063_CalcLO2Mult(&LO2, &Num2, state->AS_Data.f_LO2,
-                              state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
-
-       /*
-        *  Check the upconverter and downconverter frequency ranges
-        */
-       if ((state->AS_Data.f_LO1 < MT2063_MIN_UPC_FREQ)
-           || (state->AS_Data.f_LO1 > MT2063_MAX_UPC_FREQ))
-               status |= MT2063_UPC_RANGE;
-       if ((state->AS_Data.f_LO2 < MT2063_MIN_DNC_FREQ)
-           || (state->AS_Data.f_LO2 > MT2063_MAX_DNC_FREQ))
-               status |= MT2063_DNC_RANGE;
-       /*  LO2 Lock bit was in a different place for B0 version  */
-       if (state->tuner_id == MT2063_B0)
-               LO2LK = 0x40;
-
-       /*
-        *  If we have the same LO frequencies and we're already locked,
-        *  then skip re-programming the LO registers.
-        */
-       if ((ofLO1 != state->AS_Data.f_LO1)
-           || (ofLO2 != state->AS_Data.f_LO2)
-           || ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) !=
-               (LO1LK | LO2LK))) {
-               /*
-                * Calculate the FIFFOF register value
-                *
-                *           IF1_Actual
-                * FIFFOF = ------------ - 8 * FIFFC - 4992
-                *            f_ref/64
-                */
-               fiffof =
-                   (state->AS_Data.f_LO1 -
-                    f_in) / (state->AS_Data.f_ref / 64) - 8 * (u32) fiffc -
-                   4992;
-               if (fiffof > 0xFF)
-                       fiffof = 0xFF;
-
-               /*
-                * Place all of the calculated values into the local tuner
-                * register fields.
-                */
-               if (status >= 0) {
-                       state->reg[MT2063_REG_LO1CQ_1] = (u8) (LO1 & 0xFF);     /* DIV1q */
-                       state->reg[MT2063_REG_LO1CQ_2] = (u8) (Num1 & 0x3F);    /* NUM1q */
-                       state->reg[MT2063_REG_LO2CQ_1] = (u8) (((LO2 & 0x7F) << 1)      /* DIV2q */
-                                                                  |(Num2 >> 12));      /* NUM2q (hi) */
-                       state->reg[MT2063_REG_LO2CQ_2] = (u8) ((Num2 & 0x0FF0) >> 4);   /* NUM2q (mid) */
-                       state->reg[MT2063_REG_LO2CQ_3] = (u8) (0xE0 | (Num2 & 0x000F)); /* NUM2q (lo) */
-
-                       /*
-                        * Now write out the computed register values
-                        * IMPORTANT: There is a required order for writing
-                        *            (0x05 must follow all the others).
-                        */
-                       status |= mt2063_write(state, MT2063_REG_LO1CQ_1, &state->reg[MT2063_REG_LO1CQ_1], 5);  /* 0x01 - 0x05 */
-                       if (state->tuner_id == MT2063_B0) {
-                               /* Re-write the one-shot bits to trigger the tune operation */
-                               status |= mt2063_write(state, MT2063_REG_LO2CQ_3, &state->reg[MT2063_REG_LO2CQ_3], 1);  /* 0x05 */
-                       }
-                       /* Write out the FIFF offset only if it's changing */
-                       if (state->reg[MT2063_REG_FIFF_OFFSET] !=
-                           (u8) fiffof) {
-                               state->reg[MT2063_REG_FIFF_OFFSET] =
-                                   (u8) fiffof;
-                               status |=
-                                   mt2063_write(state,
-                                                   MT2063_REG_FIFF_OFFSET,
-                                                   &state->
-                                                   reg[MT2063_REG_FIFF_OFFSET],
-                                                   1);
-                       }
-               }
-
-               /*
-                * Check for LO's locking
-                */
-
-               if (status < 0)
-                       return status;
-
-               status = mt2063_lockStatus(state);
-               if (status < 0)
-                       return status;
-               if (!status)
-                       return -EINVAL;         /* Couldn't lock */
-
-               /*
-                * If we locked OK, assign calculated data to mt2063_state structure
-                */
-               state->f_IF1_actual = state->AS_Data.f_LO1 - f_in;
-       }
-
-       return status;
-}
-
-static const u8 MT2063B0_defaults[] = {
-       /* Reg,  Value */
-       0x19, 0x05,
-       0x1B, 0x1D,
-       0x1C, 0x1F,
-       0x1D, 0x0F,
-       0x1E, 0x3F,
-       0x1F, 0x0F,
-       0x20, 0x3F,
-       0x22, 0x21,
-       0x23, 0x3F,
-       0x24, 0x20,
-       0x25, 0x3F,
-       0x27, 0xEE,
-       0x2C, 0x27,     /*  bit at 0x20 is cleared below  */
-       0x30, 0x03,
-       0x2C, 0x07,     /*  bit at 0x20 is cleared here   */
-       0x2D, 0x87,
-       0x2E, 0xAA,
-       0x28, 0xE1,     /*  Set the FIFCrst bit here      */
-       0x28, 0xE0,     /*  Clear the FIFCrst bit here    */
-       0x00
-};
-
-/* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
-static const u8 MT2063B1_defaults[] = {
-       /* Reg,  Value */
-       0x05, 0xF0,
-       0x11, 0x10,     /* New Enable AFCsd */
-       0x19, 0x05,
-       0x1A, 0x6C,
-       0x1B, 0x24,
-       0x1C, 0x28,
-       0x1D, 0x8F,
-       0x1E, 0x14,
-       0x1F, 0x8F,
-       0x20, 0x57,
-       0x22, 0x21,     /* New - ver 1.03 */
-       0x23, 0x3C,     /* New - ver 1.10 */
-       0x24, 0x20,     /* New - ver 1.03 */
-       0x2C, 0x24,     /*  bit at 0x20 is cleared below  */
-       0x2D, 0x87,     /*  FIFFQ=0  */
-       0x2F, 0xF3,
-       0x30, 0x0C,     /* New - ver 1.11 */
-       0x31, 0x1B,     /* New - ver 1.11 */
-       0x2C, 0x04,     /*  bit at 0x20 is cleared here  */
-       0x28, 0xE1,     /*  Set the FIFCrst bit here      */
-       0x28, 0xE0,     /*  Clear the FIFCrst bit here    */
-       0x00
-};
-
-/* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
-static const u8 MT2063B3_defaults[] = {
-       /* Reg,  Value */
-       0x05, 0xF0,
-       0x19, 0x3D,
-       0x2C, 0x24,     /*  bit at 0x20 is cleared below  */
-       0x2C, 0x04,     /*  bit at 0x20 is cleared here  */
-       0x28, 0xE1,     /*  Set the FIFCrst bit here      */
-       0x28, 0xE0,     /*  Clear the FIFCrst bit here    */
-       0x00
-};
-
-static int mt2063_init(struct dvb_frontend *fe)
-{
-       u32 status;
-       struct mt2063_state *state = fe->tuner_priv;
-       u8 all_resets = 0xF0;   /* reset/load bits */
-       const u8 *def = NULL;
-       char *step;
-       u32 FCRUN;
-       s32 maxReads;
-       u32 fcu_osc;
-       u32 i;
-
-       dprintk(2, "\n");
-
-       state->rcvr_mode = MT2063_CABLE_QAM;
-
-       /*  Read the Part/Rev code from the tuner */
-       status = mt2063_read(state, MT2063_REG_PART_REV,
-                            &state->reg[MT2063_REG_PART_REV], 1);
-       if (status < 0) {
-               printk(KERN_ERR "Can't read mt2063 part ID\n");
-               return status;
-       }
-
-       /* Check the part/rev code */
-       switch (state->reg[MT2063_REG_PART_REV]) {
-       case MT2063_B0:
-               step = "B0";
-               break;
-       case MT2063_B1:
-               step = "B1";
-               break;
-       case MT2063_B2:
-               step = "B2";
-               break;
-       case MT2063_B3:
-               step = "B3";
-               break;
-       default:
-               printk(KERN_ERR "mt2063: Unknown mt2063 device ID (0x%02x)\n",
-                      state->reg[MT2063_REG_PART_REV]);
-               return -ENODEV; /*  Wrong tuner Part/Rev code */
-       }
-
-       /*  Check the 2nd byte of the Part/Rev code from the tuner */
-       status = mt2063_read(state, MT2063_REG_RSVD_3B,
-                            &state->reg[MT2063_REG_RSVD_3B], 1);
-
-       /* b7 != 0 ==> NOT MT2063 */
-       if (status < 0 || ((state->reg[MT2063_REG_RSVD_3B] & 0x80) != 0x00)) {
-               printk(KERN_ERR "mt2063: Unknown part ID (0x%02x%02x)\n",
-                      state->reg[MT2063_REG_PART_REV],
-                      state->reg[MT2063_REG_RSVD_3B]);
-               return -ENODEV; /*  Wrong tuner Part/Rev code */
-       }
-
-       printk(KERN_INFO "mt2063: detected a mt2063 %s\n", step);
-
-       /*  Reset the tuner  */
-       status = mt2063_write(state, MT2063_REG_LO2CQ_3, &all_resets, 1);
-       if (status < 0)
-               return status;
-
-       /* change all of the default values that vary from the HW reset values */
-       /*  def = (state->reg[PART_REV] == MT2063_B0) ? MT2063B0_defaults : MT2063B1_defaults; */
-       switch (state->reg[MT2063_REG_PART_REV]) {
-       case MT2063_B3:
-               def = MT2063B3_defaults;
-               break;
-
-       case MT2063_B1:
-               def = MT2063B1_defaults;
-               break;
-
-       case MT2063_B0:
-               def = MT2063B0_defaults;
-               break;
-
-       default:
-               return -ENODEV;
-               break;
-       }
-
-       while (status >= 0 && *def) {
-               u8 reg = *def++;
-               u8 val = *def++;
-               status = mt2063_write(state, reg, &val, 1);
-       }
-       if (status < 0)
-               return status;
-
-       /*  Wait for FIFF location to complete.  */
-       FCRUN = 1;
-       maxReads = 10;
-       while (status >= 0 && (FCRUN != 0) && (maxReads-- > 0)) {
-               msleep(2);
-               status = mt2063_read(state,
-                                        MT2063_REG_XO_STATUS,
-                                        &state->
-                                        reg[MT2063_REG_XO_STATUS], 1);
-               FCRUN = (state->reg[MT2063_REG_XO_STATUS] & 0x40) >> 6;
-       }
-
-       if (FCRUN != 0 || status < 0)
-               return -ENODEV;
-
-       status = mt2063_read(state,
-                          MT2063_REG_FIFFC,
-                          &state->reg[MT2063_REG_FIFFC], 1);
-       if (status < 0)
-               return status;
-
-       /* Read back all the registers from the tuner */
-       status = mt2063_read(state,
-                               MT2063_REG_PART_REV,
-                               state->reg, MT2063_REG_END_REGS);
-       if (status < 0)
-               return status;
-
-       /*  Initialize the tuner state.  */
-       state->tuner_id = state->reg[MT2063_REG_PART_REV];
-       state->AS_Data.f_ref = MT2063_REF_FREQ;
-       state->AS_Data.f_if1_Center = (state->AS_Data.f_ref / 8) *
-                                     ((u32) state->reg[MT2063_REG_FIFFC] + 640);
-       state->AS_Data.f_if1_bw = MT2063_IF1_BW;
-       state->AS_Data.f_out = 43750000UL;
-       state->AS_Data.f_out_bw = 6750000UL;
-       state->AS_Data.f_zif_bw = MT2063_ZIF_BW;
-       state->AS_Data.f_LO1_Step = state->AS_Data.f_ref / 64;
-       state->AS_Data.f_LO2_Step = MT2063_TUNE_STEP_SIZE;
-       state->AS_Data.maxH1 = MT2063_MAX_HARMONICS_1;
-       state->AS_Data.maxH2 = MT2063_MAX_HARMONICS_2;
-       state->AS_Data.f_min_LO_Separation = MT2063_MIN_LO_SEP;
-       state->AS_Data.f_if1_Request = state->AS_Data.f_if1_Center;
-       state->AS_Data.f_LO1 = 2181000000UL;
-       state->AS_Data.f_LO2 = 1486249786UL;
-       state->f_IF1_actual = state->AS_Data.f_if1_Center;
-       state->AS_Data.f_in = state->AS_Data.f_LO1 - state->f_IF1_actual;
-       state->AS_Data.f_LO1_FracN_Avoid = MT2063_LO1_FRACN_AVOID;
-       state->AS_Data.f_LO2_FracN_Avoid = MT2063_LO2_FRACN_AVOID;
-       state->num_regs = MT2063_REG_END_REGS;
-       state->AS_Data.avoidDECT = MT2063_AVOID_BOTH;
-       state->ctfilt_sw = 0;
-
-       state->CTFiltMax[0] = 69230000;
-       state->CTFiltMax[1] = 105770000;
-       state->CTFiltMax[2] = 140350000;
-       state->CTFiltMax[3] = 177110000;
-       state->CTFiltMax[4] = 212860000;
-       state->CTFiltMax[5] = 241130000;
-       state->CTFiltMax[6] = 274370000;
-       state->CTFiltMax[7] = 309820000;
-       state->CTFiltMax[8] = 342450000;
-       state->CTFiltMax[9] = 378870000;
-       state->CTFiltMax[10] = 416210000;
-       state->CTFiltMax[11] = 456500000;
-       state->CTFiltMax[12] = 495790000;
-       state->CTFiltMax[13] = 534530000;
-       state->CTFiltMax[14] = 572610000;
-       state->CTFiltMax[15] = 598970000;
-       state->CTFiltMax[16] = 635910000;
-       state->CTFiltMax[17] = 672130000;
-       state->CTFiltMax[18] = 714840000;
-       state->CTFiltMax[19] = 739660000;
-       state->CTFiltMax[20] = 770410000;
-       state->CTFiltMax[21] = 814660000;
-       state->CTFiltMax[22] = 846950000;
-       state->CTFiltMax[23] = 867820000;
-       state->CTFiltMax[24] = 915980000;
-       state->CTFiltMax[25] = 947450000;
-       state->CTFiltMax[26] = 983110000;
-       state->CTFiltMax[27] = 1021630000;
-       state->CTFiltMax[28] = 1061870000;
-       state->CTFiltMax[29] = 1098330000;
-       state->CTFiltMax[30] = 1138990000;
-
-       /*
-        **   Fetch the FCU osc value and use it and the fRef value to
-        **   scale all of the Band Max values
-        */
-
-       state->reg[MT2063_REG_CTUNE_CTRL] = 0x0A;
-       status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
-                             &state->reg[MT2063_REG_CTUNE_CTRL], 1);
-       if (status < 0)
-               return status;
-
-       /*  Read the ClearTune filter calibration value  */
-       status = mt2063_read(state, MT2063_REG_FIFFC,
-                            &state->reg[MT2063_REG_FIFFC], 1);
-       if (status < 0)
-               return status;
-
-       fcu_osc = state->reg[MT2063_REG_FIFFC];
-
-       state->reg[MT2063_REG_CTUNE_CTRL] = 0x00;
-       status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
-                             &state->reg[MT2063_REG_CTUNE_CTRL], 1);
-       if (status < 0)
-               return status;
-
-       /*  Adjust each of the values in the ClearTune filter cross-over table  */
-       for (i = 0; i < 31; i++)
-               state->CTFiltMax[i] = (state->CTFiltMax[i] / 768) * (fcu_osc + 640);
-
-       status = MT2063_SoftwareShutdown(state, 1);
-       if (status < 0)
-               return status;
-       status = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
-       if (status < 0)
-               return status;
-
-       state->init = true;
-
-       return 0;
-}
-
-static int mt2063_get_status(struct dvb_frontend *fe, u32 *tuner_status)
-{
-       struct mt2063_state *state = fe->tuner_priv;
-       int status;
-
-       dprintk(2, "\n");
-
-       if (!state->init)
-               return -ENODEV;
-
-       *tuner_status = 0;
-       status = mt2063_lockStatus(state);
-       if (status < 0)
-               return status;
-       if (status)
-               *tuner_status = TUNER_STATUS_LOCKED;
-
-       dprintk(1, "Tuner status: %d", *tuner_status);
-
-       return 0;
-}
-
-static int mt2063_release(struct dvb_frontend *fe)
-{
-       struct mt2063_state *state = fe->tuner_priv;
-
-       dprintk(2, "\n");
-
-       fe->tuner_priv = NULL;
-       kfree(state);
-
-       return 0;
-}
-
-static int mt2063_set_analog_params(struct dvb_frontend *fe,
-                                   struct analog_parameters *params)
-{
-       struct mt2063_state *state = fe->tuner_priv;
-       s32 pict_car;
-       s32 pict2chanb_vsb;
-       s32 ch_bw;
-       s32 if_mid;
-       s32 rcvr_mode;
-       int status;
-
-       dprintk(2, "\n");
-
-       if (!state->init) {
-               status = mt2063_init(fe);
-               if (status < 0)
-                       return status;
-       }
-
-       switch (params->mode) {
-       case V4L2_TUNER_RADIO:
-               pict_car = 38900000;
-               ch_bw = 8000000;
-               pict2chanb_vsb = -(ch_bw / 2);
-               rcvr_mode = MT2063_OFFAIR_ANALOG;
-               break;
-       case V4L2_TUNER_ANALOG_TV:
-               rcvr_mode = MT2063_CABLE_ANALOG;
-               if (params->std & ~V4L2_STD_MN) {
-                       pict_car = 38900000;
-                       ch_bw = 6000000;
-                       pict2chanb_vsb = -1250000;
-               } else if (params->std & V4L2_STD_PAL_G) {
-                       pict_car = 38900000;
-                       ch_bw = 7000000;
-                       pict2chanb_vsb = -1250000;
-               } else {                /* PAL/SECAM standards */
-                       pict_car = 38900000;
-                       ch_bw = 8000000;
-                       pict2chanb_vsb = -1250000;
-               }
-               break;
-       default:
-               return -EINVAL;
-       }
-       if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
-
-       state->AS_Data.f_LO2_Step = 125000;     /* FIXME: probably 5000 for FM */
-       state->AS_Data.f_out = if_mid;
-       state->AS_Data.f_out_bw = ch_bw + 750000;
-       status = MT2063_SetReceiverMode(state, rcvr_mode);
-       if (status < 0)
-               return status;
-
-       dprintk(1, "Tuning to frequency: %d, bandwidth %d, foffset %d\n",
-               params->frequency, ch_bw, pict2chanb_vsb);
-
-       status = MT2063_Tune(state, (params->frequency + (pict2chanb_vsb + (ch_bw / 2))));
-       if (status < 0)
-               return status;
-
-       state->frequency = params->frequency;
-       return 0;
-}
-
-/*
- * As defined on EN 300 429, the DVB-C roll-off factor is 0.15.
- * So, the amount of the needed bandwith is given by:
- *     Bw = Symbol_rate * (1 + 0.15)
- * As such, the maximum symbol rate supported by 6 MHz is given by:
- *     max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds
- */
-#define MAX_SYMBOL_RATE_6MHz   5217391
-
-static int mt2063_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct mt2063_state *state = fe->tuner_priv;
-       int status;
-       s32 pict_car;
-       s32 pict2chanb_vsb;
-       s32 ch_bw;
-       s32 if_mid;
-       s32 rcvr_mode;
-
-       if (!state->init) {
-               status = mt2063_init(fe);
-               if (status < 0)
-                       return status;
-       }
-
-       dprintk(2, "\n");
-
-       if (c->bandwidth_hz == 0)
-               return -EINVAL;
-       if (c->bandwidth_hz <= 6000000)
-               ch_bw = 6000000;
-       else if (c->bandwidth_hz <= 7000000)
-               ch_bw = 7000000;
-       else
-               ch_bw = 8000000;
-
-       switch (c->delivery_system) {
-       case SYS_DVBT:
-               rcvr_mode = MT2063_OFFAIR_COFDM;
-               pict_car = 36125000;
-               pict2chanb_vsb = -(ch_bw / 2);
-               break;
-       case SYS_DVBC_ANNEX_A:
-       case SYS_DVBC_ANNEX_C:
-               rcvr_mode = MT2063_CABLE_QAM;
-               pict_car = 36125000;
-               pict2chanb_vsb = -(ch_bw / 2);
-               break;
-       default:
-               return -EINVAL;
-       }
-       if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
-
-       state->AS_Data.f_LO2_Step = 125000;     /* FIXME: probably 5000 for FM */
-       state->AS_Data.f_out = if_mid;
-       state->AS_Data.f_out_bw = ch_bw + 750000;
-       status = MT2063_SetReceiverMode(state, rcvr_mode);
-       if (status < 0)
-               return status;
-
-       dprintk(1, "Tuning to frequency: %d, bandwidth %d, foffset %d\n",
-               c->frequency, ch_bw, pict2chanb_vsb);
-
-       status = MT2063_Tune(state, (c->frequency + (pict2chanb_vsb + (ch_bw / 2))));
-
-       if (status < 0)
-               return status;
-
-       state->frequency = c->frequency;
-       return 0;
-}
-
-static int mt2063_get_if_frequency(struct dvb_frontend *fe, u32 *freq)
-{
-       struct mt2063_state *state = fe->tuner_priv;
-
-       dprintk(2, "\n");
-
-       if (!state->init)
-               return -ENODEV;
-
-       *freq = state->AS_Data.f_out;
-
-       dprintk(1, "IF frequency: %d\n", *freq);
-
-       return 0;
-}
-
-static int mt2063_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
-{
-       struct mt2063_state *state = fe->tuner_priv;
-
-       dprintk(2, "\n");
-
-       if (!state->init)
-               return -ENODEV;
-
-       *bw = state->AS_Data.f_out_bw - 750000;
-
-       dprintk(1, "bandwidth: %d\n", *bw);
-
-       return 0;
-}
-
-static struct dvb_tuner_ops mt2063_ops = {
-       .info = {
-                .name = "MT2063 Silicon Tuner",
-                .frequency_min = 45000000,
-                .frequency_max = 865000000,
-                .frequency_step = 0,
-                },
-
-       .init = mt2063_init,
-       .sleep = MT2063_Sleep,
-       .get_status = mt2063_get_status,
-       .set_analog_params = mt2063_set_analog_params,
-       .set_params    = mt2063_set_params,
-       .get_if_frequency = mt2063_get_if_frequency,
-       .get_bandwidth = mt2063_get_bandwidth,
-       .release = mt2063_release,
-};
-
-struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
-                                  struct mt2063_config *config,
-                                  struct i2c_adapter *i2c)
-{
-       struct mt2063_state *state = NULL;
-
-       dprintk(2, "\n");
-
-       state = kzalloc(sizeof(struct mt2063_state), GFP_KERNEL);
-       if (state == NULL)
-               goto error;
-
-       state->config = config;
-       state->i2c = i2c;
-       state->frontend = fe;
-       state->reference = config->refclock / 1000;     /* kHz */
-       fe->tuner_priv = state;
-       fe->ops.tuner_ops = mt2063_ops;
-
-       printk(KERN_INFO "%s: Attaching MT2063\n", __func__);
-       return fe;
-
-error:
-       kfree(state);
-       return NULL;
-}
-EXPORT_SYMBOL_GPL(mt2063_attach);
-
-/*
- * Ancillary routines visible outside mt2063
- * FIXME: Remove them in favor of using standard tuner callbacks
- */
-unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe)
-{
-       struct mt2063_state *state = fe->tuner_priv;
-       int err = 0;
-
-       dprintk(2, "\n");
-
-       err = MT2063_SoftwareShutdown(state, 1);
-       if (err < 0)
-               printk(KERN_ERR "%s: Couldn't shutdown\n", __func__);
-
-       return err;
-}
-EXPORT_SYMBOL_GPL(tuner_MT2063_SoftwareShutdown);
-
-unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe)
-{
-       struct mt2063_state *state = fe->tuner_priv;
-       int err = 0;
-
-       dprintk(2, "\n");
-
-       err = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
-       if (err < 0)
-               printk(KERN_ERR "%s: Invalid parameter\n", __func__);
-
-       return err;
-}
-EXPORT_SYMBOL_GPL(tuner_MT2063_ClearPowerMaskBits);
-
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
-MODULE_DESCRIPTION("MT2063 Silicon tuner");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/mt2063.h b/drivers/media/common/tuners/mt2063.h
deleted file mode 100644 (file)
index 3f5cfd9..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef __MT2063_H__
-#define __MT2063_H__
-
-#include "dvb_frontend.h"
-
-struct mt2063_config {
-       u8 tuner_address;
-       u32 refclock;
-};
-
-#if defined(CONFIG_MEDIA_TUNER_MT2063) || (defined(CONFIG_MEDIA_TUNER_MT2063_MODULE) && defined(MODULE))
-struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
-                                  struct mt2063_config *config,
-                                  struct i2c_adapter *i2c);
-
-#else
-
-static inline struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
-                                  struct mt2063_config *config,
-                                  struct i2c_adapter *i2c)
-{
-       printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-
-/* FIXME: Should use the standard DVB attachment interfaces */
-unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe);
-unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe);
-
-#endif /* CONFIG_DVB_MT2063 */
-
-#endif /* __MT2063_H__ */
diff --git a/drivers/media/common/tuners/mt20xx.c b/drivers/media/common/tuners/mt20xx.c
deleted file mode 100644 (file)
index 0e74e97..0000000
+++ /dev/null
@@ -1,670 +0,0 @@
-/*
- * i2c tv tuner chip device driver
- * controls microtune tuners, mt2032 + mt2050 at the moment.
- *
- * This "mt20xx" module was split apart from the original "tuner" module.
- */
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include "tuner-i2c.h"
-#include "mt20xx.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable verbose debug messages");
-
-/* ---------------------------------------------------------------------- */
-
-static unsigned int optimize_vco  = 1;
-module_param(optimize_vco,      int, 0644);
-
-static unsigned int tv_antenna    = 1;
-module_param(tv_antenna,        int, 0644);
-
-static unsigned int radio_antenna;
-module_param(radio_antenna,     int, 0644);
-
-/* ---------------------------------------------------------------------- */
-
-#define MT2032 0x04
-#define MT2030 0x06
-#define MT2040 0x07
-#define MT2050 0x42
-
-static char *microtune_part[] = {
-       [ MT2030 ] = "MT2030",
-       [ MT2032 ] = "MT2032",
-       [ MT2040 ] = "MT2040",
-       [ MT2050 ] = "MT2050",
-};
-
-struct microtune_priv {
-       struct tuner_i2c_props i2c_props;
-
-       unsigned int xogc;
-       //unsigned int radio_if2;
-
-       u32 frequency;
-};
-
-static int microtune_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-
-       return 0;
-}
-
-static int microtune_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct microtune_priv *priv = fe->tuner_priv;
-       *frequency = priv->frequency;
-       return 0;
-}
-
-// IsSpurInBand()?
-static int mt2032_spurcheck(struct dvb_frontend *fe,
-                           int f1, int f2, int spectrum_from,int spectrum_to)
-{
-       struct microtune_priv *priv = fe->tuner_priv;
-       int n1=1,n2,f;
-
-       f1=f1/1000; //scale to kHz to avoid 32bit overflows
-       f2=f2/1000;
-       spectrum_from/=1000;
-       spectrum_to/=1000;
-
-       tuner_dbg("spurcheck f1=%d f2=%d  from=%d to=%d\n",
-                 f1,f2,spectrum_from,spectrum_to);
-
-       do {
-           n2=-n1;
-           f=n1*(f1-f2);
-           do {
-               n2--;
-               f=f-f2;
-               tuner_dbg("spurtest n1=%d n2=%d ftest=%d\n",n1,n2,f);
-
-               if( (f>spectrum_from) && (f<spectrum_to))
-                       tuner_dbg("mt2032 spurcheck triggered: %d\n",n1);
-           } while ( (f>(f2-spectrum_to)) || (n2>-5));
-           n1++;
-       } while (n1<5);
-
-       return 1;
-}
-
-static int mt2032_compute_freq(struct dvb_frontend *fe,
-                              unsigned int rfin,
-                              unsigned int if1, unsigned int if2,
-                              unsigned int spectrum_from,
-                              unsigned int spectrum_to,
-                              unsigned char *buf,
-                              int *ret_sel,
-                              unsigned int xogc) //all in Hz
-{
-       struct microtune_priv *priv = fe->tuner_priv;
-       unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1,
-               desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq;
-
-       fref= 5250 *1000; //5.25MHz
-       desired_lo1=rfin+if1;
-
-       lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000);
-       lo1n=lo1/8;
-       lo1a=lo1-(lo1n*8);
-
-       s=rfin/1000/1000+1090;
-
-       if(optimize_vco) {
-               if(s>1890) sel=0;
-               else if(s>1720) sel=1;
-               else if(s>1530) sel=2;
-               else if(s>1370) sel=3;
-               else sel=4; // >1090
-       }
-       else {
-               if(s>1790) sel=0; // <1958
-               else if(s>1617) sel=1;
-               else if(s>1449) sel=2;
-               else if(s>1291) sel=3;
-               else sel=4; // >1090
-       }
-       *ret_sel=sel;
-
-       lo1freq=(lo1a+8*lo1n)*fref;
-
-       tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n",
-                 rfin,lo1,lo1n,lo1a,sel,lo1freq);
-
-       desired_lo2=lo1freq-rfin-if2;
-       lo2=(desired_lo2)/fref;
-       lo2n=lo2/8;
-       lo2a=lo2-(lo2n*8);
-       lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith
-       lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000;
-
-       tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n",
-                 rfin,lo2,lo2n,lo2a,lo2num,lo2freq);
-
-       if (lo1a > 7 || lo1n < 17 || lo1n > 48 || lo2a > 7 || lo2n < 17 ||
-                       lo2n > 30) {
-               tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n",
-                          lo1a, lo1n, lo2a,lo2n);
-               return(-1);
-       }
-
-       mt2032_spurcheck(fe, lo1freq, desired_lo2,  spectrum_from, spectrum_to);
-       // should recalculate lo1 (one step up/down)
-
-       // set up MT2032 register map for transfer over i2c
-       buf[0]=lo1n-1;
-       buf[1]=lo1a | (sel<<4);
-       buf[2]=0x86; // LOGC
-       buf[3]=0x0f; //reserved
-       buf[4]=0x1f;
-       buf[5]=(lo2n-1) | (lo2a<<5);
-       if(rfin >400*1000*1000)
-               buf[6]=0xe4;
-       else
-               buf[6]=0xf4; // set PKEN per rev 1.2
-       buf[7]=8+xogc;
-       buf[8]=0xc3; //reserved
-       buf[9]=0x4e; //reserved
-       buf[10]=0xec; //reserved
-       buf[11]=(lo2num&0xff);
-       buf[12]=(lo2num>>8) |0x80; // Lo2RST
-
-       return 0;
-}
-
-static int mt2032_check_lo_lock(struct dvb_frontend *fe)
-{
-       struct microtune_priv *priv = fe->tuner_priv;
-       int try,lock=0;
-       unsigned char buf[2];
-
-       for(try=0;try<10;try++) {
-               buf[0]=0x0e;
-               tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
-               tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
-               tuner_dbg("mt2032 Reg.E=0x%02x\n",buf[0]);
-               lock=buf[0] &0x06;
-
-               if (lock==6)
-                       break;
-
-               tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]);
-               udelay(1000);
-       }
-       return lock;
-}
-
-static int mt2032_optimize_vco(struct dvb_frontend *fe,int sel,int lock)
-{
-       struct microtune_priv *priv = fe->tuner_priv;
-       unsigned char buf[2];
-       int tad1;
-
-       buf[0]=0x0f;
-       tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
-       tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
-       tuner_dbg("mt2032 Reg.F=0x%02x\n",buf[0]);
-       tad1=buf[0]&0x07;
-
-       if(tad1 ==0) return lock;
-       if(tad1 ==1) return lock;
-
-       if(tad1==2) {
-               if(sel==0)
-                       return lock;
-               else sel--;
-       }
-       else {
-               if(sel<4)
-                       sel++;
-               else
-                       return lock;
-       }
-
-       tuner_dbg("mt2032 optimize_vco: sel=%d\n",sel);
-
-       buf[0]=0x0f;
-       buf[1]=sel;
-       tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
-       lock=mt2032_check_lo_lock(fe);
-       return lock;
-}
-
-
-static void mt2032_set_if_freq(struct dvb_frontend *fe, unsigned int rfin,
-                              unsigned int if1, unsigned int if2,
-                              unsigned int from, unsigned int to)
-{
-       unsigned char buf[21];
-       int lint_try,ret,sel,lock=0;
-       struct microtune_priv *priv = fe->tuner_priv;
-
-       tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n",
-                 rfin,if1,if2,from,to);
-
-       buf[0]=0;
-       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
-       tuner_i2c_xfer_recv(&priv->i2c_props,buf,21);
-
-       buf[0]=0;
-       ret=mt2032_compute_freq(fe,rfin,if1,if2,from,to,&buf[1],&sel,priv->xogc);
-       if (ret<0)
-               return;
-
-       // send only the relevant registers per Rev. 1.2
-       buf[0]=0;
-       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,4);
-       buf[5]=5;
-       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+5,4);
-       buf[11]=11;
-       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+11,3);
-       if(ret!=3)
-               tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret);
-
-       // wait for PLLs to lock (per manual), retry LINT if not.
-       for(lint_try=0; lint_try<2; lint_try++) {
-               lock=mt2032_check_lo_lock(fe);
-
-               if(optimize_vco)
-                       lock=mt2032_optimize_vco(fe,sel,lock);
-               if(lock==6) break;
-
-               tuner_dbg("mt2032: re-init PLLs by LINT\n");
-               buf[0]=7;
-               buf[1]=0x80 +8+priv->xogc; // set LINT to re-init PLLs
-               tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
-               mdelay(10);
-               buf[1]=8+priv->xogc;
-               tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
-       }
-
-       if (lock!=6)
-               tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n");
-
-       buf[0]=2;
-       buf[1]=0x20; // LOGC for optimal phase noise
-       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
-       if (ret!=2)
-               tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
-}
-
-
-static int mt2032_set_tv_freq(struct dvb_frontend *fe,
-                             struct analog_parameters *params)
-{
-       int if2,from,to;
-
-       // signal bandwidth and picture carrier
-       if (params->std & V4L2_STD_525_60) {
-               // NTSC
-               from = 40750*1000;
-               to   = 46750*1000;
-               if2  = 45750*1000;
-       } else {
-               // PAL
-               from = 32900*1000;
-               to   = 39900*1000;
-               if2  = 38900*1000;
-       }
-
-       mt2032_set_if_freq(fe, params->frequency*62500,
-                          1090*1000*1000, if2, from, to);
-
-       return 0;
-}
-
-static int mt2032_set_radio_freq(struct dvb_frontend *fe,
-                                struct analog_parameters *params)
-{
-       struct microtune_priv *priv = fe->tuner_priv;
-       int if2;
-
-       if (params->std & V4L2_STD_525_60) {
-               tuner_dbg("pinnacle ntsc\n");
-               if2 = 41300 * 1000;
-       } else {
-               tuner_dbg("pinnacle pal\n");
-               if2 = 33300 * 1000;
-       }
-
-       // per Manual for FM tuning: first if center freq. 1085 MHz
-       mt2032_set_if_freq(fe, params->frequency * 125 / 2,
-                          1085*1000*1000,if2,if2,if2);
-
-       return 0;
-}
-
-static int mt2032_set_params(struct dvb_frontend *fe,
-                            struct analog_parameters *params)
-{
-       struct microtune_priv *priv = fe->tuner_priv;
-       int ret = -EINVAL;
-
-       switch (params->mode) {
-       case V4L2_TUNER_RADIO:
-               ret = mt2032_set_radio_freq(fe, params);
-               priv->frequency = params->frequency * 125 / 2;
-               break;
-       case V4L2_TUNER_ANALOG_TV:
-       case V4L2_TUNER_DIGITAL_TV:
-               ret = mt2032_set_tv_freq(fe, params);
-               priv->frequency = params->frequency * 62500;
-               break;
-       }
-
-       return ret;
-}
-
-static struct dvb_tuner_ops mt2032_tuner_ops = {
-       .set_analog_params = mt2032_set_params,
-       .release           = microtune_release,
-       .get_frequency     = microtune_get_frequency,
-};
-
-// Initialization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
-static int mt2032_init(struct dvb_frontend *fe)
-{
-       struct microtune_priv *priv = fe->tuner_priv;
-       unsigned char buf[21];
-       int ret,xogc,xok=0;
-
-       // Initialize Registers per spec.
-       buf[1]=2; // Index to register 2
-       buf[2]=0xff;
-       buf[3]=0x0f;
-       buf[4]=0x1f;
-       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+1,4);
-
-       buf[5]=6; // Index register 6
-       buf[6]=0xe4;
-       buf[7]=0x8f;
-       buf[8]=0xc3;
-       buf[9]=0x4e;
-       buf[10]=0xec;
-       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+5,6);
-
-       buf[12]=13;  // Index register 13
-       buf[13]=0x32;
-       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+12,2);
-
-       // Adjust XOGC (register 7), wait for XOK
-       xogc=7;
-       do {
-               tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
-               mdelay(10);
-               buf[0]=0x0e;
-               tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
-               tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
-               xok=buf[0]&0x01;
-               tuner_dbg("mt2032: xok = 0x%02x\n",xok);
-               if (xok == 1) break;
-
-               xogc--;
-               tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
-               if (xogc == 3) {
-                       xogc=4; // min. 4 per spec
-                       break;
-               }
-               buf[0]=0x07;
-               buf[1]=0x88 + xogc;
-               ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
-               if (ret!=2)
-                       tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
-       } while (xok != 1 );
-       priv->xogc=xogc;
-
-       memcpy(&fe->ops.tuner_ops, &mt2032_tuner_ops, sizeof(struct dvb_tuner_ops));
-
-       return(1);
-}
-
-static void mt2050_set_antenna(struct dvb_frontend *fe, unsigned char antenna)
-{
-       struct microtune_priv *priv = fe->tuner_priv;
-       unsigned char buf[2];
-
-       buf[0] = 6;
-       buf[1] = antenna ? 0x11 : 0x10;
-       tuner_i2c_xfer_send(&priv->i2c_props, buf, 2);
-       tuner_dbg("mt2050: enabled antenna connector %d\n", antenna);
-}
-
-static void mt2050_set_if_freq(struct dvb_frontend *fe,unsigned int freq, unsigned int if2)
-{
-       struct microtune_priv *priv = fe->tuner_priv;
-       unsigned int if1=1218*1000*1000;
-       unsigned int f_lo1,f_lo2,lo1,lo2,f_lo1_modulo,f_lo2_modulo,num1,num2,div1a,div1b,div2a,div2b;
-       int ret;
-       unsigned char buf[6];
-
-       tuner_dbg("mt2050_set_if_freq freq=%d if1=%d if2=%d\n",
-                 freq,if1,if2);
-
-       f_lo1=freq+if1;
-       f_lo1=(f_lo1/1000000)*1000000;
-
-       f_lo2=f_lo1-freq-if2;
-       f_lo2=(f_lo2/50000)*50000;
-
-       lo1=f_lo1/4000000;
-       lo2=f_lo2/4000000;
-
-       f_lo1_modulo= f_lo1-(lo1*4000000);
-       f_lo2_modulo= f_lo2-(lo2*4000000);
-
-       num1=4*f_lo1_modulo/4000000;
-       num2=4096*(f_lo2_modulo/1000)/4000;
-
-       // todo spurchecks
-
-       div1a=(lo1/12)-1;
-       div1b=lo1-(div1a+1)*12;
-
-       div2a=(lo2/8)-1;
-       div2b=lo2-(div2a+1)*8;
-
-       if (debug > 1) {
-               tuner_dbg("lo1 lo2 = %d %d\n", lo1, lo2);
-               tuner_dbg("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n",
-                         num1,num2,div1a,div1b,div2a,div2b);
-       }
-
-       buf[0]=1;
-       buf[1]= 4*div1b + num1;
-       if(freq<275*1000*1000) buf[1] = buf[1]|0x80;
-
-       buf[2]=div1a;
-       buf[3]=32*div2b + num2/256;
-       buf[4]=num2-(num2/256)*256;
-       buf[5]=div2a;
-       if(num2!=0) buf[5]=buf[5]|0x40;
-
-       if (debug > 1) {
-               int i;
-               tuner_dbg("bufs is: ");
-               for(i=0;i<6;i++)
-                       printk("%x ",buf[i]);
-               printk("\n");
-       }
-
-       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,6);
-       if (ret!=6)
-               tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret);
-}
-
-static int mt2050_set_tv_freq(struct dvb_frontend *fe,
-                             struct analog_parameters *params)
-{
-       unsigned int if2;
-
-       if (params->std & V4L2_STD_525_60) {
-               // NTSC
-               if2 = 45750*1000;
-       } else {
-               // PAL
-               if2 = 38900*1000;
-       }
-       if (V4L2_TUNER_DIGITAL_TV == params->mode) {
-               // DVB (pinnacle 300i)
-               if2 = 36150*1000;
-       }
-       mt2050_set_if_freq(fe, params->frequency*62500, if2);
-       mt2050_set_antenna(fe, tv_antenna);
-
-       return 0;
-}
-
-static int mt2050_set_radio_freq(struct dvb_frontend *fe,
-                                struct analog_parameters *params)
-{
-       struct microtune_priv *priv = fe->tuner_priv;
-       int if2;
-
-       if (params->std & V4L2_STD_525_60) {
-               tuner_dbg("pinnacle ntsc\n");
-               if2 = 41300 * 1000;
-       } else {
-               tuner_dbg("pinnacle pal\n");
-               if2 = 33300 * 1000;
-       }
-
-       mt2050_set_if_freq(fe, params->frequency * 125 / 2, if2);
-       mt2050_set_antenna(fe, radio_antenna);
-
-       return 0;
-}
-
-static int mt2050_set_params(struct dvb_frontend *fe,
-                            struct analog_parameters *params)
-{
-       struct microtune_priv *priv = fe->tuner_priv;
-       int ret = -EINVAL;
-
-       switch (params->mode) {
-       case V4L2_TUNER_RADIO:
-               ret = mt2050_set_radio_freq(fe, params);
-               priv->frequency = params->frequency * 125 / 2;
-               break;
-       case V4L2_TUNER_ANALOG_TV:
-       case V4L2_TUNER_DIGITAL_TV:
-               ret = mt2050_set_tv_freq(fe, params);
-               priv->frequency = params->frequency * 62500;
-               break;
-       }
-
-       return ret;
-}
-
-static struct dvb_tuner_ops mt2050_tuner_ops = {
-       .set_analog_params = mt2050_set_params,
-       .release           = microtune_release,
-       .get_frequency     = microtune_get_frequency,
-};
-
-static int mt2050_init(struct dvb_frontend *fe)
-{
-       struct microtune_priv *priv = fe->tuner_priv;
-       unsigned char buf[2];
-
-       buf[0] = 6;
-       buf[1] = 0x10;
-       tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); /* power */
-
-       buf[0] = 0x0f;
-       buf[1] = 0x0f;
-       tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); /* m1lo */
-
-       buf[0] = 0x0d;
-       tuner_i2c_xfer_send(&priv->i2c_props, buf, 1);
-       tuner_i2c_xfer_recv(&priv->i2c_props, buf, 1);
-
-       tuner_dbg("mt2050: sro is %x\n", buf[0]);
-
-       memcpy(&fe->ops.tuner_ops, &mt2050_tuner_ops, sizeof(struct dvb_tuner_ops));
-
-       return 0;
-}
-
-struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
-                                     struct i2c_adapter* i2c_adap,
-                                     u8 i2c_addr)
-{
-       struct microtune_priv *priv = NULL;
-       char *name;
-       unsigned char buf[21];
-       int company_code;
-
-       priv = kzalloc(sizeof(struct microtune_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-       fe->tuner_priv = priv;
-
-       priv->i2c_props.addr = i2c_addr;
-       priv->i2c_props.adap = i2c_adap;
-       priv->i2c_props.name = "mt20xx";
-
-       //priv->radio_if2 = 10700 * 1000;       /* 10.7MHz - FM radio */
-
-       memset(buf,0,sizeof(buf));
-
-       name = "unknown";
-
-       tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
-       tuner_i2c_xfer_recv(&priv->i2c_props,buf,21);
-       if (debug) {
-               int i;
-               tuner_dbg("MT20xx hexdump:");
-               for(i=0;i<21;i++) {
-                       printk(" %02x",buf[i]);
-                       if(((i+1)%8)==0) printk(" ");
-               }
-               printk("\n");
-       }
-       company_code = buf[0x11] << 8 | buf[0x12];
-       tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n",
-                  company_code,buf[0x13],buf[0x14]);
-
-
-       if (buf[0x13] < ARRAY_SIZE(microtune_part) &&
-           NULL != microtune_part[buf[0x13]])
-               name = microtune_part[buf[0x13]];
-       switch (buf[0x13]) {
-       case MT2032:
-               mt2032_init(fe);
-               break;
-       case MT2050:
-               mt2050_init(fe);
-               break;
-       default:
-               tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n",
-                          name);
-               return NULL;
-       }
-
-       strlcpy(fe->ops.tuner_ops.info.name, name,
-               sizeof(fe->ops.tuner_ops.info.name));
-       tuner_info("microtune %s found, OK\n",name);
-       return fe;
-}
-
-EXPORT_SYMBOL_GPL(microtune_attach);
-
-MODULE_DESCRIPTION("Microtune tuner driver");
-MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
-MODULE_LICENSE("GPL");
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/common/tuners/mt20xx.h b/drivers/media/common/tuners/mt20xx.h
deleted file mode 100644 (file)
index 259553a..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-    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 __MT20XX_H__
-#define __MT20XX_H__
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-
-#if defined(CONFIG_MEDIA_TUNER_MT20XX) || (defined(CONFIG_MEDIA_TUNER_MT20XX_MODULE) && defined(MODULE))
-extern struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
-                                            struct i2c_adapter* i2c_adap,
-                                            u8 i2c_addr);
-#else
-static inline struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
-                                            struct i2c_adapter* i2c_adap,
-                                            u8 i2c_addr)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* __MT20XX_H__ */
diff --git a/drivers/media/common/tuners/mt2131.c b/drivers/media/common/tuners/mt2131.c
deleted file mode 100644 (file)
index f83b0c1..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
- *
- *  Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
- *
- *  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.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/dvb/frontend.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-
-#include "mt2131.h"
-#include "mt2131_priv.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-#define dprintk(level,fmt, arg...) if (debug >= level) \
-       printk(KERN_INFO "%s: " fmt, "mt2131", ## arg)
-
-static u8 mt2131_config1[] = {
-       0x01,
-       0x50, 0x00, 0x50, 0x80, 0x00, 0x49, 0xfa, 0x88,
-       0x08, 0x77, 0x41, 0x04, 0x00, 0x00, 0x00, 0x32,
-       0x7f, 0xda, 0x4c, 0x00, 0x10, 0xaa, 0x78, 0x80,
-       0xff, 0x68, 0xa0, 0xff, 0xdd, 0x00, 0x00
-};
-
-static u8 mt2131_config2[] = {
-       0x10,
-       0x7f, 0xc8, 0x0a, 0x5f, 0x00, 0x04
-};
-
-static int mt2131_readreg(struct mt2131_priv *priv, u8 reg, u8 *val)
-{
-       struct i2c_msg msg[2] = {
-               { .addr = priv->cfg->i2c_address, .flags = 0,
-                 .buf = &reg, .len = 1 },
-               { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
-                 .buf = val,  .len = 1 },
-       };
-
-       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
-               printk(KERN_WARNING "mt2131 I2C read failed\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int mt2131_writereg(struct mt2131_priv *priv, u8 reg, u8 val)
-{
-       u8 buf[2] = { reg, val };
-       struct i2c_msg msg = { .addr = priv->cfg->i2c_address, .flags = 0,
-                              .buf = buf, .len = 2 };
-
-       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
-               printk(KERN_WARNING "mt2131 I2C write failed\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int mt2131_writeregs(struct mt2131_priv *priv,u8 *buf, u8 len)
-{
-       struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
-                              .flags = 0, .buf = buf, .len = len };
-
-       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
-               printk(KERN_WARNING "mt2131 I2C write failed (len=%i)\n",
-                      (int)len);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int mt2131_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct mt2131_priv *priv;
-       int ret=0, i;
-       u32 freq;
-       u8  if_band_center;
-       u32 f_lo1, f_lo2;
-       u32 div1, num1, div2, num2;
-       u8  b[8];
-       u8 lockval = 0;
-
-       priv = fe->tuner_priv;
-
-       freq = c->frequency / 1000;  /* Hz -> kHz */
-       dprintk(1, "%s() freq=%d\n", __func__, freq);
-
-       f_lo1 = freq + MT2131_IF1 * 1000;
-       f_lo1 = (f_lo1 / 250) * 250;
-       f_lo2 = f_lo1 - freq - MT2131_IF2;
-
-       priv->frequency =  (f_lo1 - f_lo2 - MT2131_IF2) * 1000;
-
-       /* Frequency LO1 = 16MHz * (DIV1 + NUM1/8192 ) */
-       num1 = f_lo1 * 64 / (MT2131_FREF / 128);
-       div1 = num1 / 8192;
-       num1 &= 0x1fff;
-
-       /* Frequency LO2 = 16MHz * (DIV2 + NUM2/8192 ) */
-       num2 = f_lo2 * 64 / (MT2131_FREF / 128);
-       div2 = num2 / 8192;
-       num2 &= 0x1fff;
-
-       if (freq <=   82500) if_band_center = 0x00; else
-       if (freq <=  137500) if_band_center = 0x01; else
-       if (freq <=  192500) if_band_center = 0x02; else
-       if (freq <=  247500) if_band_center = 0x03; else
-       if (freq <=  302500) if_band_center = 0x04; else
-       if (freq <=  357500) if_band_center = 0x05; else
-       if (freq <=  412500) if_band_center = 0x06; else
-       if (freq <=  467500) if_band_center = 0x07; else
-       if (freq <=  522500) if_band_center = 0x08; else
-       if (freq <=  577500) if_band_center = 0x09; else
-       if (freq <=  632500) if_band_center = 0x0A; else
-       if (freq <=  687500) if_band_center = 0x0B; else
-       if (freq <=  742500) if_band_center = 0x0C; else
-       if (freq <=  797500) if_band_center = 0x0D; else
-       if (freq <=  852500) if_band_center = 0x0E; else
-       if (freq <=  907500) if_band_center = 0x0F; else
-       if (freq <=  962500) if_band_center = 0x10; else
-       if (freq <= 1017500) if_band_center = 0x11; else
-       if (freq <= 1072500) if_band_center = 0x12; else if_band_center = 0x13;
-
-       b[0] = 1;
-       b[1] = (num1 >> 5) & 0xFF;
-       b[2] = (num1 & 0x1F);
-       b[3] = div1;
-       b[4] = (num2 >> 5) & 0xFF;
-       b[5] = num2 & 0x1F;
-       b[6] = div2;
-
-       dprintk(1, "IF1: %dMHz IF2: %dMHz\n", MT2131_IF1, MT2131_IF2);
-       dprintk(1, "PLL freq=%dkHz  band=%d\n", (int)freq, (int)if_band_center);
-       dprintk(1, "PLL f_lo1=%dkHz  f_lo2=%dkHz\n", (int)f_lo1, (int)f_lo2);
-       dprintk(1, "PLL div1=%d  num1=%d  div2=%d  num2=%d\n",
-               (int)div1, (int)num1, (int)div2, (int)num2);
-       dprintk(1, "PLL [1..6]: %2x %2x %2x %2x %2x %2x\n",
-               (int)b[1], (int)b[2], (int)b[3], (int)b[4], (int)b[5],
-               (int)b[6]);
-
-       ret = mt2131_writeregs(priv,b,7);
-       if (ret < 0)
-               return ret;
-
-       mt2131_writereg(priv, 0x0b, if_band_center);
-
-       /* Wait for lock */
-       i = 0;
-       do {
-               mt2131_readreg(priv, 0x08, &lockval);
-               if ((lockval & 0x88) == 0x88)
-                       break;
-               msleep(4);
-               i++;
-       } while (i < 10);
-
-       return ret;
-}
-
-static int mt2131_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct mt2131_priv *priv = fe->tuner_priv;
-       dprintk(1, "%s()\n", __func__);
-       *frequency = priv->frequency;
-       return 0;
-}
-
-static int mt2131_get_status(struct dvb_frontend *fe, u32 *status)
-{
-       struct mt2131_priv *priv = fe->tuner_priv;
-       u8 lock_status = 0;
-       u8 afc_status = 0;
-
-       *status = 0;
-
-       mt2131_readreg(priv, 0x08, &lock_status);
-       if ((lock_status & 0x88) == 0x88)
-               *status = TUNER_STATUS_LOCKED;
-
-       mt2131_readreg(priv, 0x09, &afc_status);
-       dprintk(1, "%s() - LO Status = 0x%x, AFC Status = 0x%x\n",
-               __func__, lock_status, afc_status);
-
-       return 0;
-}
-
-static int mt2131_init(struct dvb_frontend *fe)
-{
-       struct mt2131_priv *priv = fe->tuner_priv;
-       int ret;
-       dprintk(1, "%s()\n", __func__);
-
-       if ((ret = mt2131_writeregs(priv, mt2131_config1,
-                                   sizeof(mt2131_config1))) < 0)
-               return ret;
-
-       mt2131_writereg(priv, 0x0b, 0x09);
-       mt2131_writereg(priv, 0x15, 0x47);
-       mt2131_writereg(priv, 0x07, 0xf2);
-       mt2131_writereg(priv, 0x0b, 0x01);
-
-       if ((ret = mt2131_writeregs(priv, mt2131_config2,
-                                   sizeof(mt2131_config2))) < 0)
-               return ret;
-
-       return ret;
-}
-
-static int mt2131_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 mt2131_tuner_ops = {
-       .info = {
-               .name           = "Microtune MT2131",
-               .frequency_min  =  48000000,
-               .frequency_max  = 860000000,
-               .frequency_step =     50000,
-       },
-
-       .release       = mt2131_release,
-       .init          = mt2131_init,
-
-       .set_params    = mt2131_set_params,
-       .get_frequency = mt2131_get_frequency,
-       .get_status    = mt2131_get_status
-};
-
-struct dvb_frontend * mt2131_attach(struct dvb_frontend *fe,
-                                   struct i2c_adapter *i2c,
-                                   struct mt2131_config *cfg, u16 if1)
-{
-       struct mt2131_priv *priv = NULL;
-       u8 id = 0;
-
-       dprintk(1, "%s()\n", __func__);
-
-       priv = kzalloc(sizeof(struct mt2131_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->cfg = cfg;
-       priv->i2c = i2c;
-
-       if (mt2131_readreg(priv, 0, &id) != 0) {
-               kfree(priv);
-               return NULL;
-       }
-       if ( (id != 0x3E) && (id != 0x3F) ) {
-               printk(KERN_ERR "MT2131: Device not found at addr 0x%02x\n",
-                      cfg->i2c_address);
-               kfree(priv);
-               return NULL;
-       }
-
-       printk(KERN_INFO "MT2131: successfully identified at address 0x%02x\n",
-              cfg->i2c_address);
-       memcpy(&fe->ops.tuner_ops, &mt2131_tuner_ops,
-              sizeof(struct dvb_tuner_ops));
-
-       fe->tuner_priv = priv;
-       return fe;
-}
-EXPORT_SYMBOL(mt2131_attach);
-
-MODULE_AUTHOR("Steven Toth");
-MODULE_DESCRIPTION("Microtune MT2131 silicon tuner driver");
-MODULE_LICENSE("GPL");
-
-/*
- * Local variables:
- * c-basic-offset: 8
- */
diff --git a/drivers/media/common/tuners/mt2131.h b/drivers/media/common/tuners/mt2131.h
deleted file mode 100644 (file)
index 6632de6..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
- *
- *  Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
- *
- *  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 __MT2131_H__
-#define __MT2131_H__
-
-struct dvb_frontend;
-struct i2c_adapter;
-
-struct mt2131_config {
-       u8 i2c_address;
-       u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
-};
-
-#if defined(CONFIG_MEDIA_TUNER_MT2131) || (defined(CONFIG_MEDIA_TUNER_MT2131_MODULE) && defined(MODULE))
-extern struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
-                                         struct i2c_adapter *i2c,
-                                         struct mt2131_config *cfg,
-                                         u16 if1);
-#else
-static inline struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
-                                                struct i2c_adapter *i2c,
-                                                struct mt2131_config *cfg,
-                                                u16 if1)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_MEDIA_TUNER_MT2131 */
-
-#endif /* __MT2131_H__ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- */
diff --git a/drivers/media/common/tuners/mt2131_priv.h b/drivers/media/common/tuners/mt2131_priv.h
deleted file mode 100644 (file)
index 62aeedf..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
- *
- *  Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
- *
- *  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 __MT2131_PRIV_H__
-#define __MT2131_PRIV_H__
-
-/* Regs */
-#define MT2131_PWR              0x07
-#define MT2131_UPC_1            0x0b
-#define MT2131_AGC_RL           0x10
-#define MT2131_MISC_2           0x15
-
-/* frequency values in KHz */
-#define MT2131_IF1              1220
-#define MT2131_IF2              44000
-#define MT2131_FREF             16000
-
-struct mt2131_priv {
-       struct mt2131_config *cfg;
-       struct i2c_adapter   *i2c;
-
-       u32 frequency;
-};
-
-#endif /* __MT2131_PRIV_H__ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- */
diff --git a/drivers/media/common/tuners/mt2266.c b/drivers/media/common/tuners/mt2266.c
deleted file mode 100644 (file)
index bca4d75..0000000
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- *  Driver for Microtune MT2266 "Direct conversion low power broadband tuner"
- *
- *  Copyright (c) 2007 Olivier DANET <odanet@caramail.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.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/dvb/frontend.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "mt2266.h"
-
-#define I2C_ADDRESS 0x60
-
-#define REG_PART_REV   0
-#define REG_TUNE       1
-#define REG_BAND       6
-#define REG_BANDWIDTH  8
-#define REG_LOCK       0x12
-
-#define PART_REV 0x85
-
-struct mt2266_priv {
-       struct mt2266_config *cfg;
-       struct i2c_adapter   *i2c;
-
-       u32 frequency;
-       u32 bandwidth;
-       u8 band;
-};
-
-#define MT2266_VHF 1
-#define MT2266_UHF 0
-
-/* Here, frequencies are expressed in kiloHertz to avoid 32 bits overflows */
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-#define dprintk(args...) do { if (debug) {printk(KERN_DEBUG "MT2266: " args); printk("\n"); }} while (0)
-
-// Reads a single register
-static int mt2266_readreg(struct mt2266_priv *priv, u8 reg, u8 *val)
-{
-       struct i2c_msg msg[2] = {
-               { .addr = priv->cfg->i2c_address, .flags = 0,        .buf = &reg, .len = 1 },
-               { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val,  .len = 1 },
-       };
-       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
-               printk(KERN_WARNING "MT2266 I2C read failed\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-// Writes a single register
-static int mt2266_writereg(struct mt2266_priv *priv, u8 reg, u8 val)
-{
-       u8 buf[2] = { reg, val };
-       struct i2c_msg msg = {
-               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2
-       };
-       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
-               printk(KERN_WARNING "MT2266 I2C write failed\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-// Writes a set of consecutive registers
-static int mt2266_writeregs(struct mt2266_priv *priv,u8 *buf, u8 len)
-{
-       struct i2c_msg msg = {
-               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = len
-       };
-       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
-               printk(KERN_WARNING "MT2266 I2C write failed (len=%i)\n",(int)len);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-// Initialisation sequences
-static u8 mt2266_init1[] = { REG_TUNE, 0x00, 0x00, 0x28,
-                                0x00, 0x52, 0x99, 0x3f };
-
-static u8 mt2266_init2[] = {
-    0x17, 0x6d, 0x71, 0x61, 0xc0, 0xbf, 0xff, 0xdc, 0x00, 0x0a, 0xd4,
-    0x03, 0x64, 0x64, 0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7f, 0x5e, 0x3f, 0xff, 0xff,
-    0xff, 0x00, 0x77, 0x0f, 0x2d
-};
-
-static u8 mt2266_init_8mhz[] = { REG_BANDWIDTH, 0x22, 0x22, 0x22, 0x22,
-                                               0x22, 0x22, 0x22, 0x22 };
-
-static u8 mt2266_init_7mhz[] = { REG_BANDWIDTH, 0x32, 0x32, 0x32, 0x32,
-                                               0x32, 0x32, 0x32, 0x32 };
-
-static u8 mt2266_init_6mhz[] = { REG_BANDWIDTH, 0xa7, 0xa7, 0xa7, 0xa7,
-                                               0xa7, 0xa7, 0xa7, 0xa7 };
-
-static u8 mt2266_uhf[] = { 0x1d, 0xdc, 0x00, 0x0a, 0xd4, 0x03, 0x64, 0x64,
-                          0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14 };
-
-static u8 mt2266_vhf[] = { 0x1d, 0xfe, 0x00, 0x00, 0xb4, 0x03, 0xa5, 0xa5,
-                          0xa5, 0xa5, 0x82, 0xaa, 0xf1, 0x17, 0x80, 0x1f };
-
-#define FREF 30000       // Quartz oscillator 30 MHz
-
-static int mt2266_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct mt2266_priv *priv;
-       int ret=0;
-       u32 freq;
-       u32 tune;
-       u8  lnaband;
-       u8  b[10];
-       int i;
-       u8 band;
-
-       priv = fe->tuner_priv;
-
-       freq = priv->frequency / 1000; /* Hz -> kHz */
-       if (freq < 470000 && freq > 230000)
-               return -EINVAL; /* Gap between VHF and UHF bands */
-
-       priv->frequency = c->frequency;
-       tune = 2 * freq * (8192/16) / (FREF/16);
-       band = (freq < 300000) ? MT2266_VHF : MT2266_UHF;
-       if (band == MT2266_VHF)
-               tune *= 2;
-
-       switch (c->bandwidth_hz) {
-       case 6000000:
-               mt2266_writeregs(priv, mt2266_init_6mhz,
-                                sizeof(mt2266_init_6mhz));
-               break;
-       case 8000000:
-               mt2266_writeregs(priv, mt2266_init_8mhz,
-                                sizeof(mt2266_init_8mhz));
-               break;
-       case 7000000:
-       default:
-               mt2266_writeregs(priv, mt2266_init_7mhz,
-                                sizeof(mt2266_init_7mhz));
-               break;
-       }
-       priv->bandwidth = c->bandwidth_hz;
-
-       if (band == MT2266_VHF && priv->band == MT2266_UHF) {
-               dprintk("Switch from UHF to VHF");
-               mt2266_writereg(priv, 0x05, 0x04);
-               mt2266_writereg(priv, 0x19, 0x61);
-               mt2266_writeregs(priv, mt2266_vhf, sizeof(mt2266_vhf));
-       } else if (band == MT2266_UHF && priv->band == MT2266_VHF) {
-               dprintk("Switch from VHF to UHF");
-               mt2266_writereg(priv, 0x05, 0x52);
-               mt2266_writereg(priv, 0x19, 0x61);
-               mt2266_writeregs(priv, mt2266_uhf, sizeof(mt2266_uhf));
-       }
-       msleep(10);
-
-       if (freq <= 495000)
-               lnaband = 0xEE;
-       else if (freq <= 525000)
-               lnaband = 0xDD;
-       else if (freq <= 550000)
-               lnaband = 0xCC;
-       else if (freq <= 580000)
-               lnaband = 0xBB;
-       else if (freq <= 605000)
-               lnaband = 0xAA;
-       else if (freq <= 630000)
-               lnaband = 0x99;
-       else if (freq <= 655000)
-               lnaband = 0x88;
-       else if (freq <= 685000)
-               lnaband = 0x77;
-       else if (freq <= 710000)
-               lnaband = 0x66;
-       else if (freq <= 735000)
-               lnaband = 0x55;
-       else if (freq <= 765000)
-               lnaband = 0x44;
-       else if (freq <= 802000)
-               lnaband = 0x33;
-       else if (freq <= 840000)
-               lnaband = 0x22;
-       else
-               lnaband = 0x11;
-
-       b[0] = REG_TUNE;
-       b[1] = (tune >> 8) & 0x1F;
-       b[2] = tune & 0xFF;
-       b[3] = tune >> 13;
-       mt2266_writeregs(priv,b,4);
-
-       dprintk("set_parms: tune=%d band=%d %s",
-               (int) tune, (int) lnaband,
-               (band == MT2266_UHF) ? "UHF" : "VHF");
-       dprintk("set_parms: [1..3]: %2x %2x %2x",
-               (int) b[1], (int) b[2], (int)b[3]);
-
-       if (band == MT2266_UHF) {
-               b[0] = 0x05;
-               b[1] = (priv->band == MT2266_VHF) ? 0x52 : 0x62;
-               b[2] = lnaband;
-               mt2266_writeregs(priv, b, 3);
-       }
-
-       /* Wait for pll lock or timeout */
-       i = 0;
-       do {
-               mt2266_readreg(priv,REG_LOCK,b);
-               if (b[0] & 0x40)
-                       break;
-               msleep(10);
-               i++;
-       } while (i<10);
-       dprintk("Lock when i=%i",(int)i);
-
-       if (band == MT2266_UHF && priv->band == MT2266_VHF)
-               mt2266_writereg(priv, 0x05, 0x62);
-
-       priv->band = band;
-
-       return ret;
-}
-
-static void mt2266_calibrate(struct mt2266_priv *priv)
-{
-       mt2266_writereg(priv, 0x11, 0x03);
-       mt2266_writereg(priv, 0x11, 0x01);
-       mt2266_writeregs(priv, mt2266_init1, sizeof(mt2266_init1));
-       mt2266_writeregs(priv, mt2266_init2, sizeof(mt2266_init2));
-       mt2266_writereg(priv, 0x33, 0x5e);
-       mt2266_writereg(priv, 0x10, 0x10);
-       mt2266_writereg(priv, 0x10, 0x00);
-       mt2266_writeregs(priv, mt2266_init_8mhz, sizeof(mt2266_init_8mhz));
-       msleep(25);
-       mt2266_writereg(priv, 0x17, 0x6d);
-       mt2266_writereg(priv, 0x1c, 0x00);
-       msleep(75);
-       mt2266_writereg(priv, 0x17, 0x6d);
-       mt2266_writereg(priv, 0x1c, 0xff);
-}
-
-static int mt2266_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct mt2266_priv *priv = fe->tuner_priv;
-       *frequency = priv->frequency;
-       return 0;
-}
-
-static int mt2266_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct mt2266_priv *priv = fe->tuner_priv;
-       *bandwidth = priv->bandwidth;
-       return 0;
-}
-
-static int mt2266_init(struct dvb_frontend *fe)
-{
-       int ret;
-       struct mt2266_priv *priv = fe->tuner_priv;
-       ret = mt2266_writereg(priv, 0x17, 0x6d);
-       if (ret < 0)
-               return ret;
-       ret = mt2266_writereg(priv, 0x1c, 0xff);
-       if (ret < 0)
-               return ret;
-       return 0;
-}
-
-static int mt2266_sleep(struct dvb_frontend *fe)
-{
-       struct mt2266_priv *priv = fe->tuner_priv;
-       mt2266_writereg(priv, 0x17, 0x6d);
-       mt2266_writereg(priv, 0x1c, 0x00);
-       return 0;
-}
-
-static int mt2266_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static const struct dvb_tuner_ops mt2266_tuner_ops = {
-       .info = {
-               .name           = "Microtune MT2266",
-               .frequency_min  = 174000000,
-               .frequency_max  = 862000000,
-               .frequency_step =     50000,
-       },
-       .release       = mt2266_release,
-       .init          = mt2266_init,
-       .sleep         = mt2266_sleep,
-       .set_params    = mt2266_set_params,
-       .get_frequency = mt2266_get_frequency,
-       .get_bandwidth = mt2266_get_bandwidth
-};
-
-struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg)
-{
-       struct mt2266_priv *priv = NULL;
-       u8 id = 0;
-
-       priv = kzalloc(sizeof(struct mt2266_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->cfg      = cfg;
-       priv->i2c      = i2c;
-       priv->band     = MT2266_UHF;
-
-       if (mt2266_readreg(priv, 0, &id)) {
-               kfree(priv);
-               return NULL;
-       }
-       if (id != PART_REV) {
-               kfree(priv);
-               return NULL;
-       }
-       printk(KERN_INFO "MT2266: successfully identified\n");
-       memcpy(&fe->ops.tuner_ops, &mt2266_tuner_ops, sizeof(struct dvb_tuner_ops));
-
-       fe->tuner_priv = priv;
-       mt2266_calibrate(priv);
-       return fe;
-}
-EXPORT_SYMBOL(mt2266_attach);
-
-MODULE_AUTHOR("Olivier DANET");
-MODULE_DESCRIPTION("Microtune MT2266 silicon tuner driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/mt2266.h b/drivers/media/common/tuners/mt2266.h
deleted file mode 100644 (file)
index 4d08388..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Driver for Microtune MT2266 "Direct conversion low power broadband tuner"
- *
- *  Copyright (c) 2007 Olivier DANET <odanet@caramail.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.
- */
-
-#ifndef MT2266_H
-#define MT2266_H
-
-struct dvb_frontend;
-struct i2c_adapter;
-
-struct mt2266_config {
-       u8 i2c_address;
-};
-
-#if defined(CONFIG_MEDIA_TUNER_MT2266) || (defined(CONFIG_MEDIA_TUNER_MT2266_MODULE) && defined(MODULE))
-extern struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg);
-#else
-static inline struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_MEDIA_TUNER_MT2266
-
-#endif
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c
deleted file mode 100644 (file)
index 6133315..0000000
+++ /dev/null
@@ -1,4109 +0,0 @@
-/*
-    MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
-
-    Copyright (C) 2008 MaxLinear
-    Copyright (C) 2006 Steven Toth <stoth@linuxtv.org>
-      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
-};
-
-/* MXL5005 Tuner Register Struct */
-struct TunerReg {
-       u16 Reg_Num;    /* Tuner Register Address */
-       u16 Reg_Val;    /* Current sw programmed value waiting to be written */
-};
-
-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
-};
-
-/*
- * 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 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 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 Fref_TG;
-       u32 Fvco;
-
-       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.
-        *
-        * static u32 MXL_GetXtalInt(u32 Xtal_Freq)
-        * {
-        *      if ((Xtal_Freq % 1000000) == 0)
-        *              return (Xtal_Freq / 10000);
-        *      else
-        *              return (((Xtal_Freq / 1000000) + 1)*100);
-        * }
-        *
-        * u32 Xtal_Int = MXL_GetXtalInt(state->Fxtal);
-        * 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->config->qam_gain != 0)
-                       status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN,
-                                                  state->config->qam_gain);
-               else 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 = ARRAY_SIZE(RegAddr);
-
-       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 = ARRAY_SIZE(RegAddr);
-
-       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 = ARRAY_SIZE(RegAddr);
-
-       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@linuxtv.org>
- */
-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)
-{
-       struct mxl5005s_state *state = fe->tuner_priv;
-
-       dprintk(1, "%s()\n", __func__);
-       state->current_mode = MXL_QAM;
-       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 mxl5005s_state *state = fe->tuner_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u32 delsys = c->delivery_system;
-       u32 bw = c->bandwidth_hz;
-       u32 req_mode, req_bw = 0;
-       int ret;
-
-       dprintk(1, "%s()\n", __func__);
-
-       switch (delsys) {
-       case SYS_ATSC:
-               req_mode = MXL_ATSC;
-               req_bw  = MXL5005S_BANDWIDTH_6MHZ;
-               break;
-       case SYS_DVBC_ANNEX_B:
-               req_mode = MXL_QAM;
-               req_bw  = MXL5005S_BANDWIDTH_6MHZ;
-               break;
-       default:        /* Assume DVB-T */
-               req_mode = MXL_DVBT;
-               switch (bw) {
-               case 6000000:
-                       req_bw = MXL5005S_BANDWIDTH_6MHZ;
-                       break;
-               case 7000000:
-                       req_bw = MXL5005S_BANDWIDTH_7MHZ;
-                       break;
-               case 8000000:
-               case 0:
-                       req_bw = MXL5005S_BANDWIDTH_8MHZ;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-       }
-
-       /* Change tuner for new modulation type if reqd */
-       if (req_mode != state->current_mode ||
-           req_bw != state->Chan_Bandwidth) {
-               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__, c->frequency);
-               ret = mxl5005s_SetRfFreqHz(fe, c->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;
-
-       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");
diff --git a/drivers/media/common/tuners/mxl5005s.h b/drivers/media/common/tuners/mxl5005s.h
deleted file mode 100644 (file)
index fc8a1ff..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
-    MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
-
-    Copyright (C) 2008 MaxLinear
-    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
-
-    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;
-
-       /* Some boards need to override the built-in logic for determining
-          the gain when in QAM mode (the HVR-1600 is one such case) */
-       u8 qam_gain;
-
-       /* 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 */
-
diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c
deleted file mode 100644 (file)
index 69e453e..0000000
+++ /dev/null
@@ -1,928 +0,0 @@
-/*
- *  mxl5007t.c - driver for the MaxLinear MxL5007T silicon tuner
- *
- *  Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org>
- *
- *  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.
- */
-
-#include <linux/i2c.h>
-#include <linux/types.h>
-#include <linux/videodev2.h>
-#include "tuner-i2c.h"
-#include "mxl5007t.h"
-
-static DEFINE_MUTEX(mxl5007t_list_mutex);
-static LIST_HEAD(hybrid_tuner_instance_list);
-
-static int mxl5007t_debug;
-module_param_named(debug, mxl5007t_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debug level");
-
-/* ------------------------------------------------------------------------- */
-
-#define mxl_printk(kern, fmt, arg...) \
-       printk(kern "%s: " fmt "\n", __func__, ##arg)
-
-#define mxl_err(fmt, arg...) \
-       mxl_printk(KERN_ERR, "%d: " fmt, __LINE__, ##arg)
-
-#define mxl_warn(fmt, arg...) \
-       mxl_printk(KERN_WARNING, fmt, ##arg)
-
-#define mxl_info(fmt, arg...) \
-       mxl_printk(KERN_INFO, fmt, ##arg)
-
-#define mxl_debug(fmt, arg...)                         \
-({                                                     \
-       if (mxl5007t_debug)                             \
-               mxl_printk(KERN_DEBUG, fmt, ##arg);     \
-})
-
-#define mxl_fail(ret)                                                  \
-({                                                                     \
-       int __ret;                                                      \
-       __ret = (ret < 0);                                              \
-       if (__ret)                                                      \
-               mxl_printk(KERN_ERR, "error %d on line %d",             \
-                          ret, __LINE__);                              \
-       __ret;                                                          \
-})
-
-/* ------------------------------------------------------------------------- */
-
-#define MHz 1000000
-
-enum mxl5007t_mode {
-       MxL_MODE_ISDBT     =    0,
-       MxL_MODE_DVBT      =    1,
-       MxL_MODE_ATSC      =    2,
-       MxL_MODE_CABLE     = 0x10,
-};
-
-enum mxl5007t_chip_version {
-       MxL_UNKNOWN_ID     = 0x00,
-       MxL_5007_V1_F1     = 0x11,
-       MxL_5007_V1_F2     = 0x12,
-       MxL_5007_V4        = 0x14,
-       MxL_5007_V2_100_F1 = 0x21,
-       MxL_5007_V2_100_F2 = 0x22,
-       MxL_5007_V2_200_F1 = 0x23,
-       MxL_5007_V2_200_F2 = 0x24,
-};
-
-struct reg_pair_t {
-       u8 reg;
-       u8 val;
-};
-
-/* ------------------------------------------------------------------------- */
-
-static struct reg_pair_t init_tab[] = {
-       { 0x02, 0x06 },
-       { 0x03, 0x48 },
-       { 0x05, 0x04 },
-       { 0x06, 0x10 },
-       { 0x2e, 0x15 }, /* OVERRIDE */
-       { 0x30, 0x10 }, /* OVERRIDE */
-       { 0x45, 0x58 }, /* OVERRIDE */
-       { 0x48, 0x19 }, /* OVERRIDE */
-       { 0x52, 0x03 }, /* OVERRIDE */
-       { 0x53, 0x44 }, /* OVERRIDE */
-       { 0x6a, 0x4b }, /* OVERRIDE */
-       { 0x76, 0x00 }, /* OVERRIDE */
-       { 0x78, 0x18 }, /* OVERRIDE */
-       { 0x7a, 0x17 }, /* OVERRIDE */
-       { 0x85, 0x06 }, /* OVERRIDE */
-       { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */
-       { 0, 0 }
-};
-
-static struct reg_pair_t init_tab_cable[] = {
-       { 0x02, 0x06 },
-       { 0x03, 0x48 },
-       { 0x05, 0x04 },
-       { 0x06, 0x10 },
-       { 0x09, 0x3f },
-       { 0x0a, 0x3f },
-       { 0x0b, 0x3f },
-       { 0x2e, 0x15 }, /* OVERRIDE */
-       { 0x30, 0x10 }, /* OVERRIDE */
-       { 0x45, 0x58 }, /* OVERRIDE */
-       { 0x48, 0x19 }, /* OVERRIDE */
-       { 0x52, 0x03 }, /* OVERRIDE */
-       { 0x53, 0x44 }, /* OVERRIDE */
-       { 0x6a, 0x4b }, /* OVERRIDE */
-       { 0x76, 0x00 }, /* OVERRIDE */
-       { 0x78, 0x18 }, /* OVERRIDE */
-       { 0x7a, 0x17 }, /* OVERRIDE */
-       { 0x85, 0x06 }, /* OVERRIDE */
-       { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */
-       { 0, 0 }
-};
-
-/* ------------------------------------------------------------------------- */
-
-static struct reg_pair_t reg_pair_rftune[] = {
-       { 0x0f, 0x00 }, /* abort tune */
-       { 0x0c, 0x15 },
-       { 0x0d, 0x40 },
-       { 0x0e, 0x0e },
-       { 0x1f, 0x87 }, /* OVERRIDE */
-       { 0x20, 0x1f }, /* OVERRIDE */
-       { 0x21, 0x87 }, /* OVERRIDE */
-       { 0x22, 0x1f }, /* OVERRIDE */
-       { 0x80, 0x01 }, /* freq dependent */
-       { 0x0f, 0x01 }, /* start tune */
-       { 0, 0 }
-};
-
-/* ------------------------------------------------------------------------- */
-
-struct mxl5007t_state {
-       struct list_head hybrid_tuner_instance_list;
-       struct tuner_i2c_props i2c_props;
-
-       struct mutex lock;
-
-       struct mxl5007t_config *config;
-
-       enum mxl5007t_chip_version chip_id;
-
-       struct reg_pair_t tab_init[ARRAY_SIZE(init_tab)];
-       struct reg_pair_t tab_init_cable[ARRAY_SIZE(init_tab_cable)];
-       struct reg_pair_t tab_rftune[ARRAY_SIZE(reg_pair_rftune)];
-
-       enum mxl5007t_if_freq if_freq;
-
-       u32 frequency;
-       u32 bandwidth;
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* called by _init and _rftun to manipulate the register arrays */
-
-static void set_reg_bits(struct reg_pair_t *reg_pair, u8 reg, u8 mask, u8 val)
-{
-       unsigned int i = 0;
-
-       while (reg_pair[i].reg || reg_pair[i].val) {
-               if (reg_pair[i].reg == reg) {
-                       reg_pair[i].val &= ~mask;
-                       reg_pair[i].val |= val;
-               }
-               i++;
-
-       }
-       return;
-}
-
-static void copy_reg_bits(struct reg_pair_t *reg_pair1,
-                         struct reg_pair_t *reg_pair2)
-{
-       unsigned int i, j;
-
-       i = j = 0;
-
-       while (reg_pair1[i].reg || reg_pair1[i].val) {
-               while (reg_pair2[j].reg || reg_pair2[j].val) {
-                       if (reg_pair1[i].reg != reg_pair2[j].reg) {
-                               j++;
-                               continue;
-                       }
-                       reg_pair2[j].val = reg_pair1[i].val;
-                       break;
-               }
-               i++;
-       }
-       return;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void mxl5007t_set_mode_bits(struct mxl5007t_state *state,
-                                  enum mxl5007t_mode mode,
-                                  s32 if_diff_out_level)
-{
-       switch (mode) {
-       case MxL_MODE_ATSC:
-               set_reg_bits(state->tab_init, 0x06, 0x1f, 0x12);
-               break;
-       case MxL_MODE_DVBT:
-               set_reg_bits(state->tab_init, 0x06, 0x1f, 0x11);
-               break;
-       case MxL_MODE_ISDBT:
-               set_reg_bits(state->tab_init, 0x06, 0x1f, 0x10);
-               break;
-       case MxL_MODE_CABLE:
-               set_reg_bits(state->tab_init_cable, 0x09, 0xff, 0xc1);
-               set_reg_bits(state->tab_init_cable, 0x0a, 0xff,
-                            8 - if_diff_out_level);
-               set_reg_bits(state->tab_init_cable, 0x0b, 0xff, 0x17);
-               break;
-       default:
-               mxl_fail(-EINVAL);
-       }
-       return;
-}
-
-static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state,
-                                     enum mxl5007t_if_freq if_freq,
-                                     int invert_if)
-{
-       u8 val;
-
-       switch (if_freq) {
-       case MxL_IF_4_MHZ:
-               val = 0x00;
-               break;
-       case MxL_IF_4_5_MHZ:
-               val = 0x02;
-               break;
-       case MxL_IF_4_57_MHZ:
-               val = 0x03;
-               break;
-       case MxL_IF_5_MHZ:
-               val = 0x04;
-               break;
-       case MxL_IF_5_38_MHZ:
-               val = 0x05;
-               break;
-       case MxL_IF_6_MHZ:
-               val = 0x06;
-               break;
-       case MxL_IF_6_28_MHZ:
-               val = 0x07;
-               break;
-       case MxL_IF_9_1915_MHZ:
-               val = 0x08;
-               break;
-       case MxL_IF_35_25_MHZ:
-               val = 0x09;
-               break;
-       case MxL_IF_36_15_MHZ:
-               val = 0x0a;
-               break;
-       case MxL_IF_44_MHZ:
-               val = 0x0b;
-               break;
-       default:
-               mxl_fail(-EINVAL);
-               return;
-       }
-       set_reg_bits(state->tab_init, 0x02, 0x0f, val);
-
-       /* set inverted IF or normal IF */
-       set_reg_bits(state->tab_init, 0x02, 0x10, invert_if ? 0x10 : 0x00);
-
-       state->if_freq = if_freq;
-
-       return;
-}
-
-static void mxl5007t_set_xtal_freq_bits(struct mxl5007t_state *state,
-                                       enum mxl5007t_xtal_freq xtal_freq)
-{
-       switch (xtal_freq) {
-       case MxL_XTAL_16_MHZ:
-               /* select xtal freq & ref freq */
-               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x00);
-               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x00);
-               break;
-       case MxL_XTAL_20_MHZ:
-               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x10);
-               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x01);
-               break;
-       case MxL_XTAL_20_25_MHZ:
-               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x20);
-               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x02);
-               break;
-       case MxL_XTAL_20_48_MHZ:
-               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x30);
-               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x03);
-               break;
-       case MxL_XTAL_24_MHZ:
-               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x40);
-               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x04);
-               break;
-       case MxL_XTAL_25_MHZ:
-               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x50);
-               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x05);
-               break;
-       case MxL_XTAL_25_14_MHZ:
-               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x60);
-               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x06);
-               break;
-       case MxL_XTAL_27_MHZ:
-               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x70);
-               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x07);
-               break;
-       case MxL_XTAL_28_8_MHZ:
-               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x80);
-               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x08);
-               break;
-       case MxL_XTAL_32_MHZ:
-               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x90);
-               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x09);
-               break;
-       case MxL_XTAL_40_MHZ:
-               set_reg_bits(state->tab_init, 0x03, 0xf0, 0xa0);
-               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0a);
-               break;
-       case MxL_XTAL_44_MHZ:
-               set_reg_bits(state->tab_init, 0x03, 0xf0, 0xb0);
-               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0b);
-               break;
-       case MxL_XTAL_48_MHZ:
-               set_reg_bits(state->tab_init, 0x03, 0xf0, 0xc0);
-               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0c);
-               break;
-       case MxL_XTAL_49_3811_MHZ:
-               set_reg_bits(state->tab_init, 0x03, 0xf0, 0xd0);
-               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0d);
-               break;
-       default:
-               mxl_fail(-EINVAL);
-               return;
-       }
-
-       return;
-}
-
-static struct reg_pair_t *mxl5007t_calc_init_regs(struct mxl5007t_state *state,
-                                                 enum mxl5007t_mode mode)
-{
-       struct mxl5007t_config *cfg = state->config;
-
-       memcpy(&state->tab_init, &init_tab, sizeof(init_tab));
-       memcpy(&state->tab_init_cable, &init_tab_cable, sizeof(init_tab_cable));
-
-       mxl5007t_set_mode_bits(state, mode, cfg->if_diff_out_level);
-       mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if);
-       mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz);
-
-       set_reg_bits(state->tab_init, 0x04, 0x01, cfg->loop_thru_enable);
-       set_reg_bits(state->tab_init, 0x03, 0x08, cfg->clk_out_enable << 3);
-       set_reg_bits(state->tab_init, 0x03, 0x07, cfg->clk_out_amp);
-
-       if (mode >= MxL_MODE_CABLE) {
-               copy_reg_bits(state->tab_init, state->tab_init_cable);
-               return state->tab_init_cable;
-       } else
-               return state->tab_init;
-}
-
-/* ------------------------------------------------------------------------- */
-
-enum mxl5007t_bw_mhz {
-       MxL_BW_6MHz = 6,
-       MxL_BW_7MHz = 7,
-       MxL_BW_8MHz = 8,
-};
-
-static void mxl5007t_set_bw_bits(struct mxl5007t_state *state,
-                                enum mxl5007t_bw_mhz bw)
-{
-       u8 val;
-
-       switch (bw) {
-       case MxL_BW_6MHz:
-               val = 0x15; /* set DIG_MODEINDEX, DIG_MODEINDEX_A,
-                            * and DIG_MODEINDEX_CSF */
-               break;
-       case MxL_BW_7MHz:
-               val = 0x2a;
-               break;
-       case MxL_BW_8MHz:
-               val = 0x3f;
-               break;
-       default:
-               mxl_fail(-EINVAL);
-               return;
-       }
-       set_reg_bits(state->tab_rftune, 0x0c, 0x3f, val);
-
-       return;
-}
-
-static struct
-reg_pair_t *mxl5007t_calc_rf_tune_regs(struct mxl5007t_state *state,
-                                      u32 rf_freq, enum mxl5007t_bw_mhz bw)
-{
-       u32 dig_rf_freq = 0;
-       u32 temp;
-       u32 frac_divider = 1000000;
-       unsigned int i;
-
-       memcpy(&state->tab_rftune, &reg_pair_rftune, sizeof(reg_pair_rftune));
-
-       mxl5007t_set_bw_bits(state, bw);
-
-       /* Convert RF frequency into 16 bits =>
-        * 10 bit integer (MHz) + 6 bit fraction */
-       dig_rf_freq = rf_freq / MHz;
-
-       temp = rf_freq % MHz;
-
-       for (i = 0; i < 6; i++) {
-               dig_rf_freq <<= 1;
-               frac_divider /= 2;
-               if (temp > frac_divider) {
-                       temp -= frac_divider;
-                       dig_rf_freq++;
-               }
-       }
-
-       /* add to have shift center point by 7.8124 kHz */
-       if (temp > 7812)
-               dig_rf_freq++;
-
-       set_reg_bits(state->tab_rftune, 0x0d, 0xff, (u8) dig_rf_freq);
-       set_reg_bits(state->tab_rftune, 0x0e, 0xff, (u8) (dig_rf_freq >> 8));
-
-       if (rf_freq >= 333000000)
-               set_reg_bits(state->tab_rftune, 0x80, 0x40, 0x40);
-
-       return state->tab_rftune;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int mxl5007t_write_reg(struct mxl5007t_state *state, u8 reg, u8 val)
-{
-       u8 buf[] = { reg, val };
-       struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0,
-                              .buf = buf, .len = 2 };
-       int ret;
-
-       ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
-       if (ret != 1) {
-               mxl_err("failed!");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int mxl5007t_write_regs(struct mxl5007t_state *state,
-                              struct reg_pair_t *reg_pair)
-{
-       unsigned int i = 0;
-       int ret = 0;
-
-       while ((ret == 0) && (reg_pair[i].reg || reg_pair[i].val)) {
-               ret = mxl5007t_write_reg(state,
-                                        reg_pair[i].reg, reg_pair[i].val);
-               i++;
-       }
-       return ret;
-}
-
-static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val)
-{
-       u8 buf[2] = { 0xfb, reg };
-       struct i2c_msg msg[] = {
-               { .addr = state->i2c_props.addr, .flags = 0,
-                 .buf = buf, .len = 2 },
-               { .addr = state->i2c_props.addr, .flags = I2C_M_RD,
-                 .buf = val, .len = 1 },
-       };
-       int ret;
-
-       ret = i2c_transfer(state->i2c_props.adap, msg, 2);
-       if (ret != 2) {
-               mxl_err("failed!");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int mxl5007t_soft_reset(struct mxl5007t_state *state)
-{
-       u8 d = 0xff;
-       struct i2c_msg msg = {
-               .addr = state->i2c_props.addr, .flags = 0,
-               .buf = &d, .len = 1
-       };
-       int ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
-
-       if (ret != 1) {
-               mxl_err("failed!");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int mxl5007t_tuner_init(struct mxl5007t_state *state,
-                              enum mxl5007t_mode mode)
-{
-       struct reg_pair_t *init_regs;
-       int ret;
-
-       ret = mxl5007t_soft_reset(state);
-       if (mxl_fail(ret))
-               goto fail;
-
-       /* calculate initialization reg array */
-       init_regs = mxl5007t_calc_init_regs(state, mode);
-
-       ret = mxl5007t_write_regs(state, init_regs);
-       if (mxl_fail(ret))
-               goto fail;
-       mdelay(1);
-fail:
-       return ret;
-}
-
-static int mxl5007t_tuner_rf_tune(struct mxl5007t_state *state, u32 rf_freq_hz,
-                                 enum mxl5007t_bw_mhz bw)
-{
-       struct reg_pair_t *rf_tune_regs;
-       int ret;
-
-       /* calculate channel change reg array */
-       rf_tune_regs = mxl5007t_calc_rf_tune_regs(state, rf_freq_hz, bw);
-
-       ret = mxl5007t_write_regs(state, rf_tune_regs);
-       if (mxl_fail(ret))
-               goto fail;
-       msleep(3);
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int mxl5007t_synth_lock_status(struct mxl5007t_state *state,
-                                     int *rf_locked, int *ref_locked)
-{
-       u8 d;
-       int ret;
-
-       *rf_locked = 0;
-       *ref_locked = 0;
-
-       ret = mxl5007t_read_reg(state, 0xd8, &d);
-       if (mxl_fail(ret))
-               goto fail;
-
-       if ((d & 0x0c) == 0x0c)
-               *rf_locked = 1;
-
-       if ((d & 0x03) == 0x03)
-               *ref_locked = 1;
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
-{
-       struct mxl5007t_state *state = fe->tuner_priv;
-       int rf_locked, ref_locked, ret;
-
-       *status = 0;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       ret = mxl5007t_synth_lock_status(state, &rf_locked, &ref_locked);
-       if (mxl_fail(ret))
-               goto fail;
-       mxl_debug("%s%s", rf_locked ? "rf locked " : "",
-                 ref_locked ? "ref locked" : "");
-
-       if ((rf_locked) || (ref_locked))
-               *status |= TUNER_STATUS_LOCKED;
-fail:
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       return ret;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int mxl5007t_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u32 delsys = c->delivery_system;
-       struct mxl5007t_state *state = fe->tuner_priv;
-       enum mxl5007t_bw_mhz bw;
-       enum mxl5007t_mode mode;
-       int ret;
-       u32 freq = c->frequency;
-
-       switch (delsys) {
-       case SYS_ATSC:
-               mode = MxL_MODE_ATSC;
-               bw = MxL_BW_6MHz;
-               break;
-       case SYS_DVBC_ANNEX_B:
-               mode = MxL_MODE_CABLE;
-               bw = MxL_BW_6MHz;
-               break;
-       case SYS_DVBT:
-       case SYS_DVBT2:
-               mode = MxL_MODE_DVBT;
-               switch (c->bandwidth_hz) {
-               case 6000000:
-                       bw = MxL_BW_6MHz;
-                       break;
-               case 7000000:
-                       bw = MxL_BW_7MHz;
-                       break;
-               case 8000000:
-                       bw = MxL_BW_8MHz;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-               break;
-       default:
-               mxl_err("modulation type not supported!");
-               return -EINVAL;
-       }
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       mutex_lock(&state->lock);
-
-       ret = mxl5007t_tuner_init(state, mode);
-       if (mxl_fail(ret))
-               goto fail;
-
-       ret = mxl5007t_tuner_rf_tune(state, freq, bw);
-       if (mxl_fail(ret))
-               goto fail;
-
-       state->frequency = freq;
-       state->bandwidth = c->bandwidth_hz;
-fail:
-       mutex_unlock(&state->lock);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       return ret;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int mxl5007t_init(struct dvb_frontend *fe)
-{
-       struct mxl5007t_state *state = fe->tuner_priv;
-       int ret;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       /* wake from standby */
-       ret = mxl5007t_write_reg(state, 0x01, 0x01);
-       mxl_fail(ret);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       return ret;
-}
-
-static int mxl5007t_sleep(struct dvb_frontend *fe)
-{
-       struct mxl5007t_state *state = fe->tuner_priv;
-       int ret;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       /* enter standby mode */
-       ret = mxl5007t_write_reg(state, 0x01, 0x00);
-       mxl_fail(ret);
-       ret = mxl5007t_write_reg(state, 0x0f, 0x00);
-       mxl_fail(ret);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       return ret;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int mxl5007t_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct mxl5007t_state *state = fe->tuner_priv;
-       *frequency = state->frequency;
-       return 0;
-}
-
-static int mxl5007t_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct mxl5007t_state *state = fe->tuner_priv;
-       *bandwidth = state->bandwidth;
-       return 0;
-}
-
-static int mxl5007t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct mxl5007t_state *state = fe->tuner_priv;
-
-       *frequency = 0;
-
-       switch (state->if_freq) {
-       case MxL_IF_4_MHZ:
-               *frequency = 4000000;
-               break;
-       case MxL_IF_4_5_MHZ:
-               *frequency = 4500000;
-               break;
-       case MxL_IF_4_57_MHZ:
-               *frequency = 4570000;
-               break;
-       case MxL_IF_5_MHZ:
-               *frequency = 5000000;
-               break;
-       case MxL_IF_5_38_MHZ:
-               *frequency = 5380000;
-               break;
-       case MxL_IF_6_MHZ:
-               *frequency = 6000000;
-               break;
-       case MxL_IF_6_28_MHZ:
-               *frequency = 6280000;
-               break;
-       case MxL_IF_9_1915_MHZ:
-               *frequency = 9191500;
-               break;
-       case MxL_IF_35_25_MHZ:
-               *frequency = 35250000;
-               break;
-       case MxL_IF_36_15_MHZ:
-               *frequency = 36150000;
-               break;
-       case MxL_IF_44_MHZ:
-               *frequency = 44000000;
-               break;
-       }
-       return 0;
-}
-
-static int mxl5007t_release(struct dvb_frontend *fe)
-{
-       struct mxl5007t_state *state = fe->tuner_priv;
-
-       mutex_lock(&mxl5007t_list_mutex);
-
-       if (state)
-               hybrid_tuner_release_state(state);
-
-       mutex_unlock(&mxl5007t_list_mutex);
-
-       fe->tuner_priv = NULL;
-
-       return 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static struct dvb_tuner_ops mxl5007t_tuner_ops = {
-       .info = {
-               .name = "MaxLinear MxL5007T",
-       },
-       .init              = mxl5007t_init,
-       .sleep             = mxl5007t_sleep,
-       .set_params        = mxl5007t_set_params,
-       .get_status        = mxl5007t_get_status,
-       .get_frequency     = mxl5007t_get_frequency,
-       .get_bandwidth     = mxl5007t_get_bandwidth,
-       .release           = mxl5007t_release,
-       .get_if_frequency  = mxl5007t_get_if_frequency,
-};
-
-static int mxl5007t_get_chip_id(struct mxl5007t_state *state)
-{
-       char *name;
-       int ret;
-       u8 id;
-
-       ret = mxl5007t_read_reg(state, 0xd9, &id);
-       if (mxl_fail(ret))
-               goto fail;
-
-       switch (id) {
-       case MxL_5007_V1_F1:
-               name = "MxL5007.v1.f1";
-               break;
-       case MxL_5007_V1_F2:
-               name = "MxL5007.v1.f2";
-               break;
-       case MxL_5007_V2_100_F1:
-               name = "MxL5007.v2.100.f1";
-               break;
-       case MxL_5007_V2_100_F2:
-               name = "MxL5007.v2.100.f2";
-               break;
-       case MxL_5007_V2_200_F1:
-               name = "MxL5007.v2.200.f1";
-               break;
-       case MxL_5007_V2_200_F2:
-               name = "MxL5007.v2.200.f2";
-               break;
-       case MxL_5007_V4:
-               name = "MxL5007T.v4";
-               break;
-       default:
-               name = "MxL5007T";
-               printk(KERN_WARNING "%s: unknown rev (%02x)\n", __func__, id);
-               id = MxL_UNKNOWN_ID;
-       }
-       state->chip_id = id;
-       mxl_info("%s detected @ %d-%04x", name,
-                i2c_adapter_id(state->i2c_props.adap),
-                state->i2c_props.addr);
-       return 0;
-fail:
-       mxl_warn("unable to identify device @ %d-%04x",
-                i2c_adapter_id(state->i2c_props.adap),
-                state->i2c_props.addr);
-
-       state->chip_id = MxL_UNKNOWN_ID;
-       return ret;
-}
-
-struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
-                                    struct i2c_adapter *i2c, u8 addr,
-                                    struct mxl5007t_config *cfg)
-{
-       struct mxl5007t_state *state = NULL;
-       int instance, ret;
-
-       mutex_lock(&mxl5007t_list_mutex);
-       instance = hybrid_tuner_request_state(struct mxl5007t_state, state,
-                                             hybrid_tuner_instance_list,
-                                             i2c, addr, "mxl5007t");
-       switch (instance) {
-       case 0:
-               goto fail;
-       case 1:
-               /* new tuner instance */
-               state->config = cfg;
-
-               mutex_init(&state->lock);
-
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-
-               ret = mxl5007t_get_chip_id(state);
-
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-
-               /* check return value of mxl5007t_get_chip_id */
-               if (mxl_fail(ret))
-                       goto fail;
-               break;
-       default:
-               /* existing tuner instance */
-               break;
-       }
-       fe->tuner_priv = state;
-       mutex_unlock(&mxl5007t_list_mutex);
-
-       memcpy(&fe->ops.tuner_ops, &mxl5007t_tuner_ops,
-              sizeof(struct dvb_tuner_ops));
-
-       return fe;
-fail:
-       mutex_unlock(&mxl5007t_list_mutex);
-
-       mxl5007t_release(fe);
-       return NULL;
-}
-EXPORT_SYMBOL_GPL(mxl5007t_attach);
-MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver");
-MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.2");
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/common/tuners/mxl5007t.h b/drivers/media/common/tuners/mxl5007t.h
deleted file mode 100644 (file)
index aa3eea0..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- *  mxl5007t.h - driver for the MaxLinear MxL5007T silicon tuner
- *
- *  Copyright (C) 2008 Michael Krufky <mkrufky@linuxtv.org>
- *
- *  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 __MXL5007T_H__
-#define __MXL5007T_H__
-
-#include "dvb_frontend.h"
-
-/* ------------------------------------------------------------------------- */
-
-enum mxl5007t_if_freq {
-       MxL_IF_4_MHZ,      /*  4000000 */
-       MxL_IF_4_5_MHZ,    /*  4500000 */
-       MxL_IF_4_57_MHZ,   /*  4570000 */
-       MxL_IF_5_MHZ,      /*  5000000 */
-       MxL_IF_5_38_MHZ,   /*  5380000 */
-       MxL_IF_6_MHZ,      /*  6000000 */
-       MxL_IF_6_28_MHZ,   /*  6280000 */
-       MxL_IF_9_1915_MHZ, /*  9191500 */
-       MxL_IF_35_25_MHZ,  /* 35250000 */
-       MxL_IF_36_15_MHZ,  /* 36150000 */
-       MxL_IF_44_MHZ,     /* 44000000 */
-};
-
-enum mxl5007t_xtal_freq {
-       MxL_XTAL_16_MHZ,      /* 16000000 */
-       MxL_XTAL_20_MHZ,      /* 20000000 */
-       MxL_XTAL_20_25_MHZ,   /* 20250000 */
-       MxL_XTAL_20_48_MHZ,   /* 20480000 */
-       MxL_XTAL_24_MHZ,      /* 24000000 */
-       MxL_XTAL_25_MHZ,      /* 25000000 */
-       MxL_XTAL_25_14_MHZ,   /* 25140000 */
-       MxL_XTAL_27_MHZ,      /* 27000000 */
-       MxL_XTAL_28_8_MHZ,    /* 28800000 */
-       MxL_XTAL_32_MHZ,      /* 32000000 */
-       MxL_XTAL_40_MHZ,      /* 40000000 */
-       MxL_XTAL_44_MHZ,      /* 44000000 */
-       MxL_XTAL_48_MHZ,      /* 48000000 */
-       MxL_XTAL_49_3811_MHZ, /* 49381100 */
-};
-
-enum mxl5007t_clkout_amp {
-       MxL_CLKOUT_AMP_0_94V = 0,
-       MxL_CLKOUT_AMP_0_53V = 1,
-       MxL_CLKOUT_AMP_0_37V = 2,
-       MxL_CLKOUT_AMP_0_28V = 3,
-       MxL_CLKOUT_AMP_0_23V = 4,
-       MxL_CLKOUT_AMP_0_20V = 5,
-       MxL_CLKOUT_AMP_0_17V = 6,
-       MxL_CLKOUT_AMP_0_15V = 7,
-};
-
-struct mxl5007t_config {
-       s32 if_diff_out_level;
-       enum mxl5007t_clkout_amp clk_out_amp;
-       enum mxl5007t_xtal_freq xtal_freq_hz;
-       enum mxl5007t_if_freq if_freq_hz;
-       unsigned int invert_if:1;
-       unsigned int loop_thru_enable:1;
-       unsigned int clk_out_enable:1;
-};
-
-#if defined(CONFIG_MEDIA_TUNER_MXL5007T) || (defined(CONFIG_MEDIA_TUNER_MXL5007T_MODULE) && defined(MODULE))
-extern struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
-                                           struct i2c_adapter *i2c, u8 addr,
-                                           struct mxl5007t_config *cfg);
-#else
-static inline struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
-                                                  struct i2c_adapter *i2c,
-                                                  u8 addr,
-                                                  struct mxl5007t_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* __MXL5007T_H__ */
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
-
diff --git a/drivers/media/common/tuners/qt1010.c b/drivers/media/common/tuners/qt1010.c
deleted file mode 100644 (file)
index bdc39e1..0000000
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- *  Driver for Quantek QT1010 silicon tuner
- *
- *  Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
- *                     Aapo Tahkola <aet@rasterburn.org>
- *
- *  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.
- */
-#include "qt1010.h"
-#include "qt1010_priv.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "QT1010: " args); \
-       } while (0)
-
-/* read single register */
-static int qt1010_readreg(struct qt1010_priv *priv, u8 reg, u8 *val)
-{
-       struct i2c_msg msg[2] = {
-               { .addr = priv->cfg->i2c_address,
-                 .flags = 0, .buf = &reg, .len = 1 },
-               { .addr = priv->cfg->i2c_address,
-                 .flags = I2C_M_RD, .buf = val, .len = 1 },
-       };
-
-       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
-               printk(KERN_WARNING "qt1010 I2C read failed\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-/* write single register */
-static int qt1010_writereg(struct qt1010_priv *priv, u8 reg, u8 val)
-{
-       u8 buf[2] = { reg, val };
-       struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
-                              .flags = 0, .buf = buf, .len = 2 };
-
-       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
-               printk(KERN_WARNING "qt1010 I2C write failed\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-/* dump all registers */
-static void qt1010_dump_regs(struct qt1010_priv *priv)
-{
-       u8 reg, val;
-
-       for (reg = 0; ; reg++) {
-               if (reg % 16 == 0) {
-                       if (reg)
-                               printk(KERN_CONT "\n");
-                       printk(KERN_DEBUG "%02x:", reg);
-               }
-               if (qt1010_readreg(priv, reg, &val) == 0)
-                       printk(KERN_CONT " %02x", val);
-               else
-                       printk(KERN_CONT " --");
-               if (reg == 0x2f)
-                       break;
-       }
-       printk(KERN_CONT "\n");
-}
-
-static int qt1010_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct qt1010_priv *priv;
-       int err;
-       u32 freq, div, mod1, mod2;
-       u8 i, tmpval, reg05;
-       qt1010_i2c_oper_t rd[48] = {
-               { QT1010_WR, 0x01, 0x80 },
-               { QT1010_WR, 0x02, 0x3f },
-               { QT1010_WR, 0x05, 0xff }, /* 02 c write */
-               { QT1010_WR, 0x06, 0x44 },
-               { QT1010_WR, 0x07, 0xff }, /* 04 c write */
-               { QT1010_WR, 0x08, 0x08 },
-               { QT1010_WR, 0x09, 0xff }, /* 06 c write */
-               { QT1010_WR, 0x0a, 0xff }, /* 07 c write */
-               { QT1010_WR, 0x0b, 0xff }, /* 08 c write */
-               { QT1010_WR, 0x0c, 0xe1 },
-               { QT1010_WR, 0x1a, 0xff }, /* 10 c write */
-               { QT1010_WR, 0x1b, 0x00 },
-               { QT1010_WR, 0x1c, 0x89 },
-               { QT1010_WR, 0x11, 0xff }, /* 13 c write */
-               { QT1010_WR, 0x12, 0xff }, /* 14 c write */
-               { QT1010_WR, 0x22, 0xff }, /* 15 c write */
-               { QT1010_WR, 0x1e, 0x00 },
-               { QT1010_WR, 0x1e, 0xd0 },
-               { QT1010_RD, 0x22, 0xff }, /* 16 c read */
-               { QT1010_WR, 0x1e, 0x00 },
-               { QT1010_RD, 0x05, 0xff }, /* 20 c read */
-               { QT1010_RD, 0x22, 0xff }, /* 21 c read */
-               { QT1010_WR, 0x23, 0xd0 },
-               { QT1010_WR, 0x1e, 0x00 },
-               { QT1010_WR, 0x1e, 0xe0 },
-               { QT1010_RD, 0x23, 0xff }, /* 25 c read */
-               { QT1010_RD, 0x23, 0xff }, /* 26 c read */
-               { QT1010_WR, 0x1e, 0x00 },
-               { QT1010_WR, 0x24, 0xd0 },
-               { QT1010_WR, 0x1e, 0x00 },
-               { QT1010_WR, 0x1e, 0xf0 },
-               { QT1010_RD, 0x24, 0xff }, /* 31 c read */
-               { QT1010_WR, 0x1e, 0x00 },
-               { QT1010_WR, 0x14, 0x7f },
-               { QT1010_WR, 0x15, 0x7f },
-               { QT1010_WR, 0x05, 0xff }, /* 35 c write */
-               { QT1010_WR, 0x06, 0x00 },
-               { QT1010_WR, 0x15, 0x1f },
-               { QT1010_WR, 0x16, 0xff },
-               { QT1010_WR, 0x18, 0xff },
-               { QT1010_WR, 0x1f, 0xff }, /* 40 c write */
-               { QT1010_WR, 0x20, 0xff }, /* 41 c write */
-               { QT1010_WR, 0x21, 0x53 },
-               { QT1010_WR, 0x25, 0xff }, /* 43 c write */
-               { QT1010_WR, 0x26, 0x15 },
-               { QT1010_WR, 0x00, 0xff }, /* 45 c write */
-               { QT1010_WR, 0x02, 0x00 },
-               { QT1010_WR, 0x01, 0x00 }
-       };
-
-#define FREQ1 32000000 /* 32 MHz */
-#define FREQ2  4000000 /* 4 MHz Quartz oscillator in the stick? */
-
-       priv = fe->tuner_priv;
-       freq = c->frequency;
-       div = (freq + QT1010_OFFSET) / QT1010_STEP;
-       freq = (div * QT1010_STEP) - QT1010_OFFSET;
-       mod1 = (freq + QT1010_OFFSET) % FREQ1;
-       mod2 = (freq + QT1010_OFFSET) % FREQ2;
-       priv->frequency = freq;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
-
-       /* reg 05 base value */
-       if      (freq < 290000000) reg05 = 0x14; /* 290 MHz */
-       else if (freq < 610000000) reg05 = 0x34; /* 610 MHz */
-       else if (freq < 802000000) reg05 = 0x54; /* 802 MHz */
-       else                       reg05 = 0x74;
-
-       /* 0x5 */
-       rd[2].val = reg05;
-
-       /* 07 - set frequency: 32 MHz scale */
-       rd[4].val = (freq + QT1010_OFFSET) / FREQ1;
-
-       /* 09 - changes every 8/24 MHz */
-       if (mod1 < 8000000) rd[6].val = 0x1d;
-       else                rd[6].val = 0x1c;
-
-       /* 0a - set frequency: 4 MHz scale (max 28 MHz) */
-       if      (mod1 < 1*FREQ2) rd[7].val = 0x09; /*  +0 MHz */
-       else if (mod1 < 2*FREQ2) rd[7].val = 0x08; /*  +4 MHz */
-       else if (mod1 < 3*FREQ2) rd[7].val = 0x0f; /*  +8 MHz */
-       else if (mod1 < 4*FREQ2) rd[7].val = 0x0e; /* +12 MHz */
-       else if (mod1 < 5*FREQ2) rd[7].val = 0x0d; /* +16 MHz */
-       else if (mod1 < 6*FREQ2) rd[7].val = 0x0c; /* +20 MHz */
-       else if (mod1 < 7*FREQ2) rd[7].val = 0x0b; /* +24 MHz */
-       else                     rd[7].val = 0x0a; /* +28 MHz */
-
-       /* 0b - changes every 2/2 MHz */
-       if (mod2 < 2000000) rd[8].val = 0x45;
-       else                rd[8].val = 0x44;
-
-       /* 1a - set frequency: 125 kHz scale (max 3875 kHz)*/
-       tmpval = 0x78; /* byte, overflows intentionally */
-       rd[10].val = tmpval-((mod2/QT1010_STEP)*0x08);
-
-       /* 11 */
-       rd[13].val = 0xfd; /* TODO: correct value calculation */
-
-       /* 12 */
-       rd[14].val = 0x91; /* TODO: correct value calculation */
-
-       /* 22 */
-       if      (freq < 450000000) rd[15].val = 0xd0; /* 450 MHz */
-       else if (freq < 482000000) rd[15].val = 0xd1; /* 482 MHz */
-       else if (freq < 514000000) rd[15].val = 0xd4; /* 514 MHz */
-       else if (freq < 546000000) rd[15].val = 0xd7; /* 546 MHz */
-       else if (freq < 610000000) rd[15].val = 0xda; /* 610 MHz */
-       else                       rd[15].val = 0xd0;
-
-       /* 05 */
-       rd[35].val = (reg05 & 0xf0);
-
-       /* 1f */
-       if      (mod1 <  8000000) tmpval = 0x00;
-       else if (mod1 < 12000000) tmpval = 0x01;
-       else if (mod1 < 16000000) tmpval = 0x02;
-       else if (mod1 < 24000000) tmpval = 0x03;
-       else if (mod1 < 28000000) tmpval = 0x04;
-       else                      tmpval = 0x05;
-       rd[40].val = (priv->reg1f_init_val + 0x0e + tmpval);
-
-       /* 20 */
-       if      (mod1 <  8000000) tmpval = 0x00;
-       else if (mod1 < 12000000) tmpval = 0x01;
-       else if (mod1 < 20000000) tmpval = 0x02;
-       else if (mod1 < 24000000) tmpval = 0x03;
-       else if (mod1 < 28000000) tmpval = 0x04;
-       else                      tmpval = 0x05;
-       rd[41].val = (priv->reg20_init_val + 0x0d + tmpval);
-
-       /* 25 */
-       rd[43].val = priv->reg25_init_val;
-
-       /* 00 */
-       rd[45].val = 0x92; /* TODO: correct value calculation */
-
-       dprintk("freq:%u 05:%02x 07:%02x 09:%02x 0a:%02x 0b:%02x " \
-               "1a:%02x 11:%02x 12:%02x 22:%02x 05:%02x 1f:%02x " \
-               "20:%02x 25:%02x 00:%02x", \
-               freq, rd[2].val, rd[4].val, rd[6].val, rd[7].val, rd[8].val, \
-               rd[10].val, rd[13].val, rd[14].val, rd[15].val, rd[35].val, \
-               rd[40].val, rd[41].val, rd[43].val, rd[45].val);
-
-       for (i = 0; i < ARRAY_SIZE(rd); i++) {
-               if (rd[i].oper == QT1010_WR) {
-                       err = qt1010_writereg(priv, rd[i].reg, rd[i].val);
-               } else { /* read is required to proper locking */
-                       err = qt1010_readreg(priv, rd[i].reg, &tmpval);
-               }
-               if (err) return err;
-       }
-
-       if (debug)
-               qt1010_dump_regs(priv);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
-
-       return 0;
-}
-
-static int qt1010_init_meas1(struct qt1010_priv *priv,
-                            u8 oper, u8 reg, u8 reg_init_val, u8 *retval)
-{
-       u8 i, val1, val2;
-       int err;
-
-       qt1010_i2c_oper_t i2c_data[] = {
-               { QT1010_WR, reg, reg_init_val },
-               { QT1010_WR, 0x1e, 0x00 },
-               { QT1010_WR, 0x1e, oper },
-               { QT1010_RD, reg, 0xff }
-       };
-
-       for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
-               if (i2c_data[i].oper == QT1010_WR) {
-                       err = qt1010_writereg(priv, i2c_data[i].reg,
-                                             i2c_data[i].val);
-               } else {
-                       err = qt1010_readreg(priv, i2c_data[i].reg, &val2);
-               }
-               if (err) return err;
-       }
-
-       do {
-               val1 = val2;
-               err = qt1010_readreg(priv, reg, &val2);
-               if (err) return err;
-               dprintk("compare reg:%02x %02x %02x", reg, val1, val2);
-       } while (val1 != val2);
-       *retval = val1;
-
-       return qt1010_writereg(priv, 0x1e, 0x00);
-}
-
-static int qt1010_init_meas2(struct qt1010_priv *priv,
-                           u8 reg_init_val, u8 *retval)
-{
-       u8 i, val;
-       int err;
-       qt1010_i2c_oper_t i2c_data[] = {
-               { QT1010_WR, 0x07, reg_init_val },
-               { QT1010_WR, 0x22, 0xd0 },
-               { QT1010_WR, 0x1e, 0x00 },
-               { QT1010_WR, 0x1e, 0xd0 },
-               { QT1010_RD, 0x22, 0xff },
-               { QT1010_WR, 0x1e, 0x00 },
-               { QT1010_WR, 0x22, 0xff }
-       };
-       for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
-               if (i2c_data[i].oper == QT1010_WR) {
-                       err = qt1010_writereg(priv, i2c_data[i].reg,
-                                             i2c_data[i].val);
-               } else {
-                       err = qt1010_readreg(priv, i2c_data[i].reg, &val);
-               }
-               if (err) return err;
-       }
-       *retval = val;
-       return 0;
-}
-
-static int qt1010_init(struct dvb_frontend *fe)
-{
-       struct qt1010_priv *priv = fe->tuner_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int err = 0;
-       u8 i, tmpval, *valptr = NULL;
-
-       qt1010_i2c_oper_t i2c_data[] = {
-               { QT1010_WR, 0x01, 0x80 },
-               { QT1010_WR, 0x0d, 0x84 },
-               { QT1010_WR, 0x0e, 0xb7 },
-               { QT1010_WR, 0x2a, 0x23 },
-               { QT1010_WR, 0x2c, 0xdc },
-               { QT1010_M1, 0x25, 0x40 }, /* get reg 25 init value */
-               { QT1010_M1, 0x81, 0xff }, /* get reg 25 init value */
-               { QT1010_WR, 0x2b, 0x70 },
-               { QT1010_WR, 0x2a, 0x23 },
-               { QT1010_M1, 0x26, 0x08 },
-               { QT1010_M1, 0x82, 0xff },
-               { QT1010_WR, 0x05, 0x14 },
-               { QT1010_WR, 0x06, 0x44 },
-               { QT1010_WR, 0x07, 0x28 },
-               { QT1010_WR, 0x08, 0x0b },
-               { QT1010_WR, 0x11, 0xfd },
-               { QT1010_M1, 0x22, 0x0d },
-               { QT1010_M1, 0xd0, 0xff },
-               { QT1010_WR, 0x06, 0x40 },
-               { QT1010_WR, 0x16, 0xf0 },
-               { QT1010_WR, 0x02, 0x38 },
-               { QT1010_WR, 0x03, 0x18 },
-               { QT1010_WR, 0x20, 0xe0 },
-               { QT1010_M1, 0x1f, 0x20 }, /* get reg 1f init value */
-               { QT1010_M1, 0x84, 0xff }, /* get reg 1f init value */
-               { QT1010_RD, 0x20, 0x20 }, /* get reg 20 init value */
-               { QT1010_WR, 0x03, 0x19 },
-               { QT1010_WR, 0x02, 0x3f },
-               { QT1010_WR, 0x21, 0x53 },
-               { QT1010_RD, 0x21, 0xff },
-               { QT1010_WR, 0x11, 0xfd },
-               { QT1010_WR, 0x05, 0x34 },
-               { QT1010_WR, 0x06, 0x44 },
-               { QT1010_WR, 0x08, 0x08 }
-       };
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
-
-       for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
-               switch (i2c_data[i].oper) {
-               case QT1010_WR:
-                       err = qt1010_writereg(priv, i2c_data[i].reg,
-                                             i2c_data[i].val);
-                       break;
-               case QT1010_RD:
-                       if (i2c_data[i].val == 0x20)
-                               valptr = &priv->reg20_init_val;
-                       else
-                               valptr = &tmpval;
-                       err = qt1010_readreg(priv, i2c_data[i].reg, valptr);
-                       break;
-               case QT1010_M1:
-                       if (i2c_data[i].val == 0x25)
-                               valptr = &priv->reg25_init_val;
-                       else if (i2c_data[i].val == 0x1f)
-                               valptr = &priv->reg1f_init_val;
-                       else
-                               valptr = &tmpval;
-                       err = qt1010_init_meas1(priv, i2c_data[i+1].reg,
-                                               i2c_data[i].reg,
-                                               i2c_data[i].val, valptr);
-                       i++;
-                       break;
-               }
-               if (err) return err;
-       }
-
-       for (i = 0x31; i < 0x3a; i++) /* 0x31 - 0x39 */
-               if ((err = qt1010_init_meas2(priv, i, &tmpval)))
-                       return err;
-
-       c->frequency = 545000000; /* Sigmatek DVB-110 545000000 */
-                                     /* MSI Megasky 580 GL861 533000000 */
-       return qt1010_set_params(fe);
-}
-
-static int qt1010_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static int qt1010_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct qt1010_priv *priv = fe->tuner_priv;
-       *frequency = priv->frequency;
-       return 0;
-}
-
-static int qt1010_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       *frequency = 36125000;
-       return 0;
-}
-
-static const struct dvb_tuner_ops qt1010_tuner_ops = {
-       .info = {
-               .name           = "Quantek QT1010",
-               .frequency_min  = QT1010_MIN_FREQ,
-               .frequency_max  = QT1010_MAX_FREQ,
-               .frequency_step = QT1010_STEP,
-       },
-
-       .release       = qt1010_release,
-       .init          = qt1010_init,
-       /* TODO: implement sleep */
-
-       .set_params    = qt1010_set_params,
-       .get_frequency = qt1010_get_frequency,
-       .get_if_frequency = qt1010_get_if_frequency,
-};
-
-struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe,
-                                   struct i2c_adapter *i2c,
-                                   struct qt1010_config *cfg)
-{
-       struct qt1010_priv *priv = NULL;
-       u8 id;
-
-       priv = kzalloc(sizeof(struct qt1010_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->cfg = cfg;
-       priv->i2c = i2c;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
-
-
-       /* Try to detect tuner chip. Probably this is not correct register. */
-       if (qt1010_readreg(priv, 0x29, &id) != 0 || (id != 0x39)) {
-               kfree(priv);
-               return NULL;
-       }
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
-
-       printk(KERN_INFO "Quantek QT1010 successfully identified.\n");
-       memcpy(&fe->ops.tuner_ops, &qt1010_tuner_ops,
-              sizeof(struct dvb_tuner_ops));
-
-       fe->tuner_priv = priv;
-       return fe;
-}
-EXPORT_SYMBOL(qt1010_attach);
-
-MODULE_DESCRIPTION("Quantek QT1010 silicon tuner driver");
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>");
-MODULE_VERSION("0.1");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/qt1010.h b/drivers/media/common/tuners/qt1010.h
deleted file mode 100644 (file)
index 807fb7b..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *  Driver for Quantek QT1010 silicon tuner
- *
- *  Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
- *                     Aapo Tahkola <aet@rasterburn.org>
- *
- *  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 QT1010_H
-#define QT1010_H
-
-#include "dvb_frontend.h"
-
-struct qt1010_config {
-       u8 i2c_address;
-};
-
-/**
- * Attach a qt1010 tuner to the supplied frontend structure.
- *
- * @param fe   frontend to attach to
- * @param i2c  i2c adapter to use
- * @param cfg  tuner hw based configuration
- * @return fe  pointer on success, NULL on failure
- */
-#if defined(CONFIG_MEDIA_TUNER_QT1010) || (defined(CONFIG_MEDIA_TUNER_QT1010_MODULE) && defined(MODULE))
-extern struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe,
-                                         struct i2c_adapter *i2c,
-                                         struct qt1010_config *cfg);
-#else
-static inline struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe,
-                                                struct i2c_adapter *i2c,
-                                                struct qt1010_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_MEDIA_TUNER_QT1010
-
-#endif
diff --git a/drivers/media/common/tuners/qt1010_priv.h b/drivers/media/common/tuners/qt1010_priv.h
deleted file mode 100644 (file)
index 2c42d3f..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- *  Driver for Quantek QT1010 silicon tuner
- *
- *  Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
- *                     Aapo Tahkola <aet@rasterburn.org>
- *
- *  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 QT1010_PRIV_H
-#define QT1010_PRIV_H
-
-/*
-reg def meaning
-=== === =======
-00  00  ?
-01  a0  ? operation start/stop; start=80, stop=00
-02  00  ?
-03  19  ?
-04  00  ?
-05  00  ? maybe band selection
-06  00  ?
-07  2b  set frequency: 32 MHz scale, n*32 MHz
-08  0b  ?
-09  10  ? changes every 8/24 MHz; values 1d/1c
-0a  08  set frequency: 4 MHz scale, n*4 MHz
-0b  41  ? changes every 2/2 MHz; values 45/45
-0c  e1  ?
-0d  94  ?
-0e  b6  ?
-0f  2c  ?
-10  10  ?
-11  f1  ? maybe device specified adjustment
-12  11  ? maybe device specified adjustment
-13  3f  ?
-14  1f  ?
-15  3f  ?
-16  ff  ?
-17  ff  ?
-18  f7  ?
-19  80  ?
-1a  d0  set frequency: 125 kHz scale, n*125 kHz
-1b  00  ?
-1c  89  ?
-1d  00  ?
-1e  00  ? looks like operation register; write cmd here, read result from 1f-26
-1f  20  ? chip initialization
-20  e0  ? chip initialization
-21  20  ?
-22  d0  ?
-23  d0  ?
-24  d0  ?
-25  40  ? chip initialization
-26  08  ?
-27  29  ?
-28  55  ?
-29  39  ?
-2a  13  ?
-2b  01  ?
-2c  ea  ?
-2d  00  ?
-2e  00  ? not used?
-2f  00  ? not used?
-*/
-
-#define QT1010_STEP         125000 /*  125 kHz used by Windows drivers,
-                                     hw could be more precise but we don't
-                                     know how to use */
-#define QT1010_MIN_FREQ   48000000 /*   48 MHz */
-#define QT1010_MAX_FREQ  860000000 /*  860 MHz */
-#define QT1010_OFFSET   1246000000 /* 1246 MHz */
-
-#define QT1010_WR 0
-#define QT1010_RD 1
-#define QT1010_M1 3
-
-typedef struct {
-       u8 oper, reg, val;
-} qt1010_i2c_oper_t;
-
-struct qt1010_priv {
-       struct qt1010_config *cfg;
-       struct i2c_adapter   *i2c;
-
-       u8 reg1f_init_val;
-       u8 reg20_init_val;
-       u8 reg25_init_val;
-
-       u32 frequency;
-};
-
-#endif
diff --git a/drivers/media/common/tuners/tda18212.c b/drivers/media/common/tuners/tda18212.c
deleted file mode 100644 (file)
index 5d9f028..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * NXP TDA18212HN silicon tuner driver
- *
- * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
- *
- *    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.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "tda18212.h"
-
-struct tda18212_priv {
-       struct tda18212_config *cfg;
-       struct i2c_adapter *i2c;
-
-       u32 if_frequency;
-};
-
-/* write multiple registers */
-static int tda18212_wr_regs(struct tda18212_priv *priv, u8 reg, u8 *val,
-       int len)
-{
-       int ret;
-       u8 buf[len+1];
-       struct i2c_msg msg[1] = {
-               {
-                       .addr = priv->cfg->i2c_address,
-                       .flags = 0,
-                       .len = sizeof(buf),
-                       .buf = buf,
-               }
-       };
-
-       buf[0] = reg;
-       memcpy(&buf[1], val, len);
-
-       ret = i2c_transfer(priv->i2c, msg, 1);
-       if (ret == 1) {
-               ret = 0;
-       } else {
-               dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
-                               "len=%d\n", KBUILD_MODNAME, ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-       return ret;
-}
-
-/* read multiple registers */
-static int tda18212_rd_regs(struct tda18212_priv *priv, u8 reg, u8 *val,
-       int len)
-{
-       int ret;
-       u8 buf[len];
-       struct i2c_msg msg[2] = {
-               {
-                       .addr = priv->cfg->i2c_address,
-                       .flags = 0,
-                       .len = 1,
-                       .buf = &reg,
-               }, {
-                       .addr = priv->cfg->i2c_address,
-                       .flags = I2C_M_RD,
-                       .len = sizeof(buf),
-                       .buf = buf,
-               }
-       };
-
-       ret = i2c_transfer(priv->i2c, msg, 2);
-       if (ret == 2) {
-               memcpy(val, buf, len);
-               ret = 0;
-       } else {
-               dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
-                               "len=%d\n", KBUILD_MODNAME, ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-
-       return ret;
-}
-
-/* write single register */
-static int tda18212_wr_reg(struct tda18212_priv *priv, u8 reg, u8 val)
-{
-       return tda18212_wr_regs(priv, reg, &val, 1);
-}
-
-/* read single register */
-static int tda18212_rd_reg(struct tda18212_priv *priv, u8 reg, u8 *val)
-{
-       return tda18212_rd_regs(priv, reg, val, 1);
-}
-
-#if 0 /* keep, useful when developing driver */
-static void tda18212_dump_regs(struct tda18212_priv *priv)
-{
-       int i;
-       u8 buf[256];
-
-       #define TDA18212_RD_LEN 32
-       for (i = 0; i < sizeof(buf); i += TDA18212_RD_LEN)
-               tda18212_rd_regs(priv, i, &buf[i], TDA18212_RD_LEN);
-
-       print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 32, 1, buf,
-               sizeof(buf), true);
-
-       return;
-}
-#endif
-
-static int tda18212_set_params(struct dvb_frontend *fe)
-{
-       struct tda18212_priv *priv = fe->tuner_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret, i;
-       u32 if_khz;
-       u8 buf[9];
-       #define DVBT_6   0
-       #define DVBT_7   1
-       #define DVBT_8   2
-       #define DVBT2_6  3
-       #define DVBT2_7  4
-       #define DVBT2_8  5
-       #define DVBC_6   6
-       #define DVBC_8   7
-       static const u8 bw_params[][3] = {
-                    /* reg:   0f    13    23 */
-               [DVBT_6]  = { 0xb3, 0x20, 0x03 },
-               [DVBT_7]  = { 0xb3, 0x31, 0x01 },
-               [DVBT_8]  = { 0xb3, 0x22, 0x01 },
-               [DVBT2_6] = { 0xbc, 0x20, 0x03 },
-               [DVBT2_7] = { 0xbc, 0x72, 0x03 },
-               [DVBT2_8] = { 0xbc, 0x22, 0x01 },
-               [DVBC_6]  = { 0x92, 0x50, 0x03 },
-               [DVBC_8]  = { 0x92, 0x53, 0x03 },
-       };
-
-       dev_dbg(&priv->i2c->dev,
-                       "%s: delivery_system=%d frequency=%d bandwidth_hz=%d\n",
-                       __func__, c->delivery_system, c->frequency,
-                       c->bandwidth_hz);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
-
-       switch (c->delivery_system) {
-       case SYS_DVBT:
-               switch (c->bandwidth_hz) {
-               case 6000000:
-                       if_khz = priv->cfg->if_dvbt_6;
-                       i = DVBT_6;
-                       break;
-               case 7000000:
-                       if_khz = priv->cfg->if_dvbt_7;
-                       i = DVBT_7;
-                       break;
-               case 8000000:
-                       if_khz = priv->cfg->if_dvbt_8;
-                       i = DVBT_8;
-                       break;
-               default:
-                       ret = -EINVAL;
-                       goto error;
-               }
-               break;
-       case SYS_DVBT2:
-               switch (c->bandwidth_hz) {
-               case 6000000:
-                       if_khz = priv->cfg->if_dvbt2_6;
-                       i = DVBT2_6;
-                       break;
-               case 7000000:
-                       if_khz = priv->cfg->if_dvbt2_7;
-                       i = DVBT2_7;
-                       break;
-               case 8000000:
-                       if_khz = priv->cfg->if_dvbt2_8;
-                       i = DVBT2_8;
-                       break;
-               default:
-                       ret = -EINVAL;
-                       goto error;
-               }
-               break;
-       case SYS_DVBC_ANNEX_A:
-       case SYS_DVBC_ANNEX_C:
-               if_khz = priv->cfg->if_dvbc;
-               i = DVBC_8;
-               break;
-       default:
-               ret = -EINVAL;
-               goto error;
-       }
-
-       ret = tda18212_wr_reg(priv, 0x23, bw_params[i][2]);
-       if (ret)
-               goto error;
-
-       ret = tda18212_wr_reg(priv, 0x06, 0x00);
-       if (ret)
-               goto error;
-
-       ret = tda18212_wr_reg(priv, 0x0f, bw_params[i][0]);
-       if (ret)
-               goto error;
-
-       buf[0] = 0x02;
-       buf[1] = bw_params[i][1];
-       buf[2] = 0x03; /* default value */
-       buf[3] = DIV_ROUND_CLOSEST(if_khz, 50);
-       buf[4] = ((c->frequency / 1000) >> 16) & 0xff;
-       buf[5] = ((c->frequency / 1000) >>  8) & 0xff;
-       buf[6] = ((c->frequency / 1000) >>  0) & 0xff;
-       buf[7] = 0xc1;
-       buf[8] = 0x01;
-       ret = tda18212_wr_regs(priv, 0x12, buf, sizeof(buf));
-       if (ret)
-               goto error;
-
-       /* actual IF rounded as it is on register */
-       priv->if_frequency = buf[3] * 50 * 1000;
-
-exit:
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
-
-       return ret;
-
-error:
-       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
-       goto exit;
-}
-
-static int tda18212_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct tda18212_priv *priv = fe->tuner_priv;
-
-       *frequency = priv->if_frequency;
-
-       return 0;
-}
-
-static int tda18212_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static const struct dvb_tuner_ops tda18212_tuner_ops = {
-       .info = {
-               .name           = "NXP TDA18212",
-
-               .frequency_min  =  48000000,
-               .frequency_max  = 864000000,
-               .frequency_step =      1000,
-       },
-
-       .release       = tda18212_release,
-
-       .set_params    = tda18212_set_params,
-       .get_if_frequency = tda18212_get_if_frequency,
-};
-
-struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
-       struct i2c_adapter *i2c, struct tda18212_config *cfg)
-{
-       struct tda18212_priv *priv = NULL;
-       int ret;
-       u8 uninitialized_var(val);
-
-       priv = kzalloc(sizeof(struct tda18212_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->cfg = cfg;
-       priv->i2c = i2c;
-       fe->tuner_priv = priv;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
-
-       /* check if the tuner is there */
-       ret = tda18212_rd_reg(priv, 0x00, &val);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
-
-       dev_dbg(&priv->i2c->dev, "%s: ret=%d chip id=%02x\n", __func__, ret,
-                       val);
-       if (ret || val != 0xc7) {
-               kfree(priv);
-               return NULL;
-       }
-
-       dev_info(&priv->i2c->dev,
-                       "%s: NXP TDA18212HN successfully identified\n",
-                       KBUILD_MODNAME);
-
-       memcpy(&fe->ops.tuner_ops, &tda18212_tuner_ops,
-               sizeof(struct dvb_tuner_ops));
-
-       return fe;
-}
-EXPORT_SYMBOL(tda18212_attach);
-
-MODULE_DESCRIPTION("NXP TDA18212HN silicon tuner driver");
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/tda18212.h b/drivers/media/common/tuners/tda18212.h
deleted file mode 100644 (file)
index 9bd5da4..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * NXP TDA18212HN silicon tuner driver
- *
- * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
- *
- *    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.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef TDA18212_H
-#define TDA18212_H
-
-#include "dvb_frontend.h"
-
-struct tda18212_config {
-       u8 i2c_address;
-
-       u16 if_dvbt_6;
-       u16 if_dvbt_7;
-       u16 if_dvbt_8;
-       u16 if_dvbt2_5;
-       u16 if_dvbt2_6;
-       u16 if_dvbt2_7;
-       u16 if_dvbt2_8;
-       u16 if_dvbc;
-};
-
-#if defined(CONFIG_MEDIA_TUNER_TDA18212) || \
-       (defined(CONFIG_MEDIA_TUNER_TDA18212_MODULE) && defined(MODULE))
-extern struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
-       struct i2c_adapter *i2c, struct tda18212_config *cfg);
-#else
-static inline struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
-       struct i2c_adapter *i2c, struct tda18212_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif
diff --git a/drivers/media/common/tuners/tda18218.c b/drivers/media/common/tuners/tda18218.c
deleted file mode 100644 (file)
index 8a6f9ca..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * NXP TDA18218HN silicon tuner driver
- *
- * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
- *
- *    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.
- */
-
-#include "tda18218.h"
-#include "tda18218_priv.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-/* write multiple registers */
-static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
-{
-       int ret = 0;
-       u8 buf[1+len], quotient, remainder, i, msg_len, msg_len_max;
-       struct i2c_msg msg[1] = {
-               {
-                       .addr = priv->cfg->i2c_address,
-                       .flags = 0,
-                       .buf = buf,
-               }
-       };
-
-       msg_len_max = priv->cfg->i2c_wr_max - 1;
-       quotient = len / msg_len_max;
-       remainder = len % msg_len_max;
-       msg_len = msg_len_max;
-       for (i = 0; (i <= quotient && remainder); i++) {
-               if (i == quotient)  /* set len of the last msg */
-                       msg_len = remainder;
-
-               msg[0].len = msg_len + 1;
-               buf[0] = reg + i * msg_len_max;
-               memcpy(&buf[1], &val[i * msg_len_max], msg_len);
-
-               ret = i2c_transfer(priv->i2c, msg, 1);
-               if (ret != 1)
-                       break;
-       }
-
-       if (ret == 1) {
-               ret = 0;
-       } else {
-               warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-
-       return ret;
-}
-
-/* read multiple registers */
-static int tda18218_rd_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
-{
-       int ret;
-       u8 buf[reg+len]; /* we must start read always from reg 0x00 */
-       struct i2c_msg msg[2] = {
-               {
-                       .addr = priv->cfg->i2c_address,
-                       .flags = 0,
-                       .len = 1,
-                       .buf = "\x00",
-               }, {
-                       .addr = priv->cfg->i2c_address,
-                       .flags = I2C_M_RD,
-                       .len = sizeof(buf),
-                       .buf = buf,
-               }
-       };
-
-       ret = i2c_transfer(priv->i2c, msg, 2);
-       if (ret == 2) {
-               memcpy(val, &buf[reg], len);
-               ret = 0;
-       } else {
-               warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len);
-               ret = -EREMOTEIO;
-       }
-
-       return ret;
-}
-
-/* write single register */
-static int tda18218_wr_reg(struct tda18218_priv *priv, u8 reg, u8 val)
-{
-       return tda18218_wr_regs(priv, reg, &val, 1);
-}
-
-/* read single register */
-
-static int tda18218_rd_reg(struct tda18218_priv *priv, u8 reg, u8 *val)
-{
-       return tda18218_rd_regs(priv, reg, val, 1);
-}
-
-static int tda18218_set_params(struct dvb_frontend *fe)
-{
-       struct tda18218_priv *priv = fe->tuner_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u32 bw = c->bandwidth_hz;
-       int ret;
-       u8 buf[3], i, BP_Filter, LP_Fc;
-       u32 LO_Frac;
-       /* TODO: find out correct AGC algorithm */
-       u8 agc[][2] = {
-               { R20_AGC11, 0x60 },
-               { R23_AGC21, 0x02 },
-               { R20_AGC11, 0xa0 },
-               { R23_AGC21, 0x09 },
-               { R20_AGC11, 0xe0 },
-               { R23_AGC21, 0x0c },
-               { R20_AGC11, 0x40 },
-               { R23_AGC21, 0x01 },
-               { R20_AGC11, 0x80 },
-               { R23_AGC21, 0x08 },
-               { R20_AGC11, 0xc0 },
-               { R23_AGC21, 0x0b },
-               { R24_AGC22, 0x1c },
-               { R24_AGC22, 0x0c },
-       };
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
-
-       /* low-pass filter cut-off frequency */
-       if (bw <= 6000000) {
-               LP_Fc = 0;
-               priv->if_frequency = 3000000;
-       } else if (bw <= 7000000) {
-               LP_Fc = 1;
-               priv->if_frequency = 3500000;
-       } else {
-               LP_Fc = 2;
-               priv->if_frequency = 4000000;
-       }
-
-       LO_Frac = c->frequency + priv->if_frequency;
-
-       /* band-pass filter */
-       if (LO_Frac < 188000000)
-               BP_Filter = 3;
-       else if (LO_Frac < 253000000)
-               BP_Filter = 4;
-       else if (LO_Frac < 343000000)
-               BP_Filter = 5;
-       else
-               BP_Filter = 6;
-
-       buf[0] = (priv->regs[R1A_IF1] & ~7) | BP_Filter; /* BP_Filter */
-       buf[1] = (priv->regs[R1B_IF2] & ~3) | LP_Fc; /* LP_Fc */
-       buf[2] = priv->regs[R1C_AGC2B];
-       ret = tda18218_wr_regs(priv, R1A_IF1, buf, 3);
-       if (ret)
-               goto error;
-
-       buf[0] = (LO_Frac / 1000) >> 12; /* LO_Frac_0 */
-       buf[1] = (LO_Frac / 1000) >> 4; /* LO_Frac_1 */
-       buf[2] = (LO_Frac / 1000) << 4 |
-               (priv->regs[R0C_MD5] & 0x0f); /* LO_Frac_2 */
-       ret = tda18218_wr_regs(priv, R0A_MD3, buf, 3);
-       if (ret)
-               goto error;
-
-       buf[0] = priv->regs[R0F_MD8] | (1 << 6); /* Freq_prog_Start */
-       ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
-       if (ret)
-               goto error;
-
-       buf[0] = priv->regs[R0F_MD8] & ~(1 << 6); /* Freq_prog_Start */
-       ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
-       if (ret)
-               goto error;
-
-       /* trigger AGC */
-       for (i = 0; i < ARRAY_SIZE(agc); i++) {
-               ret = tda18218_wr_reg(priv, agc[i][0], agc[i][1]);
-               if (ret)
-                       goto error;
-       }
-
-error:
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
-
-       if (ret)
-               dbg("%s: failed ret:%d", __func__, ret);
-
-       return ret;
-}
-
-static int tda18218_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct tda18218_priv *priv = fe->tuner_priv;
-       *frequency = priv->if_frequency;
-       dbg("%s: if=%d", __func__, *frequency);
-       return 0;
-}
-
-static int tda18218_sleep(struct dvb_frontend *fe)
-{
-       struct tda18218_priv *priv = fe->tuner_priv;
-       int ret;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
-
-       /* standby */
-       ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
-
-       if (ret)
-               dbg("%s: failed ret:%d", __func__, ret);
-
-       return ret;
-}
-
-static int tda18218_init(struct dvb_frontend *fe)
-{
-       struct tda18218_priv *priv = fe->tuner_priv;
-       int ret;
-
-       /* TODO: calibrations */
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
-
-       ret = tda18218_wr_regs(priv, R00_ID, priv->regs, TDA18218_NUM_REGS);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
-
-       if (ret)
-               dbg("%s: failed ret:%d", __func__, ret);
-
-       return ret;
-}
-
-static int tda18218_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static const struct dvb_tuner_ops tda18218_tuner_ops = {
-       .info = {
-               .name           = "NXP TDA18218",
-
-               .frequency_min  = 174000000,
-               .frequency_max  = 864000000,
-               .frequency_step =      1000,
-       },
-
-       .release       = tda18218_release,
-       .init          = tda18218_init,
-       .sleep         = tda18218_sleep,
-
-       .set_params    = tda18218_set_params,
-
-       .get_if_frequency = tda18218_get_if_frequency,
-};
-
-struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
-       struct i2c_adapter *i2c, struct tda18218_config *cfg)
-{
-       struct tda18218_priv *priv = NULL;
-       u8 uninitialized_var(val);
-       int ret;
-       /* chip default registers values */
-       static u8 def_regs[] = {
-               0xc0, 0x88, 0x00, 0x8e, 0x03, 0x00, 0x00, 0xd0, 0x00, 0x40,
-               0x00, 0x00, 0x07, 0xff, 0x84, 0x09, 0x00, 0x13, 0x00, 0x00,
-               0x01, 0x84, 0x09, 0xf0, 0x19, 0x0a, 0x8e, 0x69, 0x98, 0x01,
-               0x00, 0x58, 0x10, 0x40, 0x8c, 0x00, 0x0c, 0x48, 0x85, 0xc9,
-               0xa7, 0x00, 0x00, 0x00, 0x30, 0x81, 0x80, 0x00, 0x39, 0x00,
-               0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xf6
-       };
-
-       priv = kzalloc(sizeof(struct tda18218_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->cfg = cfg;
-       priv->i2c = i2c;
-       fe->tuner_priv = priv;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
-
-       /* check if the tuner is there */
-       ret = tda18218_rd_reg(priv, R00_ID, &val);
-       dbg("%s: ret:%d chip ID:%02x", __func__, ret, val);
-       if (ret || val != def_regs[R00_ID]) {
-               kfree(priv);
-               return NULL;
-       }
-
-       info("NXP TDA18218HN successfully identified.");
-
-       memcpy(&fe->ops.tuner_ops, &tda18218_tuner_ops,
-               sizeof(struct dvb_tuner_ops));
-       memcpy(priv->regs, def_regs, sizeof(def_regs));
-
-       /* loop-through enabled chip default register values */
-       if (priv->cfg->loop_through) {
-               priv->regs[R17_PD1] = 0xb0;
-               priv->regs[R18_PD2] = 0x59;
-       }
-
-       /* standby */
-       ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
-       if (ret)
-               dbg("%s: failed ret:%d", __func__, ret);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
-
-       return fe;
-}
-EXPORT_SYMBOL(tda18218_attach);
-
-MODULE_DESCRIPTION("NXP TDA18218HN silicon tuner driver");
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/tda18218.h b/drivers/media/common/tuners/tda18218.h
deleted file mode 100644 (file)
index b4180d1..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * NXP TDA18218HN silicon tuner driver
- *
- * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
- *
- *    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 TDA18218_H
-#define TDA18218_H
-
-#include "dvb_frontend.h"
-
-struct tda18218_config {
-       u8 i2c_address;
-       u8 i2c_wr_max;
-       u8 loop_through:1;
-};
-
-#if defined(CONFIG_MEDIA_TUNER_TDA18218) || \
-       (defined(CONFIG_MEDIA_TUNER_TDA18218_MODULE) && defined(MODULE))
-extern struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
-       struct i2c_adapter *i2c, struct tda18218_config *cfg);
-#else
-static inline struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
-       struct i2c_adapter *i2c, struct tda18218_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif
diff --git a/drivers/media/common/tuners/tda18218_priv.h b/drivers/media/common/tuners/tda18218_priv.h
deleted file mode 100644 (file)
index dc52b72..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * NXP TDA18218HN silicon tuner driver
- *
- * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
- *
- *    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 TDA18218_PRIV_H
-#define TDA18218_PRIV_H
-
-#define LOG_PREFIX "tda18218"
-
-#undef dbg
-#define dbg(f, arg...) \
-       if (debug) \
-               printk(KERN_DEBUG   LOG_PREFIX": " f "\n" , ## arg)
-#undef err
-#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
-#undef info
-#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
-#undef warn
-#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
-
-#define R00_ID         0x00    /* ID byte */
-#define R01_R1         0x01    /* Read byte 1 */
-#define R02_R2         0x02    /* Read byte 2 */
-#define R03_R3         0x03    /* Read byte 3 */
-#define R04_R4         0x04    /* Read byte 4 */
-#define R05_R5         0x05    /* Read byte 5 */
-#define R06_R6         0x06    /* Read byte 6 */
-#define R07_MD1        0x07    /* Main divider byte 1 */
-#define R08_PSM1       0x08    /* PSM byte 1 */
-#define R09_MD2        0x09    /* Main divider byte 2 */
-#define R0A_MD3        0x0a    /* Main divider byte 1 */
-#define R0B_MD4        0x0b    /* Main divider byte 4 */
-#define R0C_MD5        0x0c    /* Main divider byte 5 */
-#define R0D_MD6        0x0d    /* Main divider byte 6 */
-#define R0E_MD7        0x0e    /* Main divider byte 7 */
-#define R0F_MD8        0x0f    /* Main divider byte 8 */
-#define R10_CD1        0x10    /* Call divider byte 1 */
-#define R11_CD2        0x11    /* Call divider byte 2 */
-#define R12_CD3        0x12    /* Call divider byte 3 */
-#define R13_CD4        0x13    /* Call divider byte 4 */
-#define R14_CD5        0x14    /* Call divider byte 5 */
-#define R15_CD6        0x15    /* Call divider byte 6 */
-#define R16_CD7        0x16    /* Call divider byte 7 */
-#define R17_PD1        0x17    /* Power-down byte 1 */
-#define R18_PD2        0x18    /* Power-down byte 2 */
-#define R19_XTOUT      0x19    /* XTOUT byte */
-#define R1A_IF1        0x1a    /* IF byte 1 */
-#define R1B_IF2        0x1b    /* IF byte 2 */
-#define R1C_AGC2B      0x1c    /* AGC2b byte */
-#define R1D_PSM2       0x1d    /* PSM byte 2 */
-#define R1E_PSM3       0x1e    /* PSM byte 3 */
-#define R1F_PSM4       0x1f    /* PSM byte 4 */
-#define R20_AGC11      0x20    /* AGC1 byte 1 */
-#define R21_AGC12      0x21    /* AGC1 byte 2 */
-#define R22_AGC13      0x22    /* AGC1 byte 3 */
-#define R23_AGC21      0x23    /* AGC2 byte 1 */
-#define R24_AGC22      0x24    /* AGC2 byte 2 */
-#define R25_AAGC       0x25    /* Analog AGC byte */
-#define R26_RC         0x26    /* RC byte */
-#define R27_RSSI       0x27    /* RSSI byte */
-#define R28_IRCAL1     0x28    /* IR CAL byte 1 */
-#define R29_IRCAL2     0x29    /* IR CAL byte 2 */
-#define R2A_IRCAL3     0x2a    /* IR CAL byte 3 */
-#define R2B_IRCAL4     0x2b    /* IR CAL byte 4 */
-#define R2C_RFCAL1     0x2c    /* RF CAL byte 1 */
-#define R2D_RFCAL2     0x2d    /* RF CAL byte 2 */
-#define R2E_RFCAL3     0x2e    /* RF CAL byte 3 */
-#define R2F_RFCAL4     0x2f    /* RF CAL byte 4 */
-#define R30_RFCAL5     0x30    /* RF CAL byte 5 */
-#define R31_RFCAL6     0x31    /* RF CAL byte 6 */
-#define R32_RFCAL7     0x32    /* RF CAL byte 7 */
-#define R33_RFCAL8     0x33    /* RF CAL byte 8 */
-#define R34_RFCAL9     0x34    /* RF CAL byte 9 */
-#define R35_RFCAL10    0x35    /* RF CAL byte 10 */
-#define R36_RFCALRAM1  0x36    /* RF CAL RAM byte 1 */
-#define R37_RFCALRAM2  0x37    /* RF CAL RAM byte 2 */
-#define R38_MARGIN     0x38    /* Margin byte */
-#define R39_FMAX1      0x39    /* Fmax byte 1 */
-#define R3A_FMAX2      0x3a    /* Fmax byte 2 */
-
-#define TDA18218_NUM_REGS 59
-
-struct tda18218_priv {
-       struct tda18218_config *cfg;
-       struct i2c_adapter *i2c;
-
-       u32 if_frequency;
-
-       u8 regs[TDA18218_NUM_REGS];
-};
-
-#endif
diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c
deleted file mode 100644 (file)
index 39c6457..0000000
+++ /dev/null
@@ -1,703 +0,0 @@
-/*
-    tda18271-common.c - driver for the Philips / NXP TDA18271 silicon tuner
-
-    Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
-
-    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.
-*/
-
-#include "tda18271-priv.h"
-
-static int tda18271_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       enum tda18271_i2c_gate gate;
-       int ret = 0;
-
-       switch (priv->gate) {
-       case TDA18271_GATE_DIGITAL:
-       case TDA18271_GATE_ANALOG:
-               gate = priv->gate;
-               break;
-       case TDA18271_GATE_AUTO:
-       default:
-               switch (priv->mode) {
-               case TDA18271_DIGITAL:
-                       gate = TDA18271_GATE_DIGITAL;
-                       break;
-               case TDA18271_ANALOG:
-               default:
-                       gate = TDA18271_GATE_ANALOG;
-                       break;
-               }
-       }
-
-       switch (gate) {
-       case TDA18271_GATE_ANALOG:
-               if (fe->ops.analog_ops.i2c_gate_ctrl)
-                       ret = fe->ops.analog_ops.i2c_gate_ctrl(fe, enable);
-               break;
-       case TDA18271_GATE_DIGITAL:
-               if (fe->ops.i2c_gate_ctrl)
-                       ret = fe->ops.i2c_gate_ctrl(fe, enable);
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
-
-       return ret;
-};
-
-/*---------------------------------------------------------------------*/
-
-static void tda18271_dump_regs(struct dvb_frontend *fe, int extended)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-
-       tda_reg("=== TDA18271 REG DUMP ===\n");
-       tda_reg("ID_BYTE            = 0x%02x\n", 0xff & regs[R_ID]);
-       tda_reg("THERMO_BYTE        = 0x%02x\n", 0xff & regs[R_TM]);
-       tda_reg("POWER_LEVEL_BYTE   = 0x%02x\n", 0xff & regs[R_PL]);
-       tda_reg("EASY_PROG_BYTE_1   = 0x%02x\n", 0xff & regs[R_EP1]);
-       tda_reg("EASY_PROG_BYTE_2   = 0x%02x\n", 0xff & regs[R_EP2]);
-       tda_reg("EASY_PROG_BYTE_3   = 0x%02x\n", 0xff & regs[R_EP3]);
-       tda_reg("EASY_PROG_BYTE_4   = 0x%02x\n", 0xff & regs[R_EP4]);
-       tda_reg("EASY_PROG_BYTE_5   = 0x%02x\n", 0xff & regs[R_EP5]);
-       tda_reg("CAL_POST_DIV_BYTE  = 0x%02x\n", 0xff & regs[R_CPD]);
-       tda_reg("CAL_DIV_BYTE_1     = 0x%02x\n", 0xff & regs[R_CD1]);
-       tda_reg("CAL_DIV_BYTE_2     = 0x%02x\n", 0xff & regs[R_CD2]);
-       tda_reg("CAL_DIV_BYTE_3     = 0x%02x\n", 0xff & regs[R_CD3]);
-       tda_reg("MAIN_POST_DIV_BYTE = 0x%02x\n", 0xff & regs[R_MPD]);
-       tda_reg("MAIN_DIV_BYTE_1    = 0x%02x\n", 0xff & regs[R_MD1]);
-       tda_reg("MAIN_DIV_BYTE_2    = 0x%02x\n", 0xff & regs[R_MD2]);
-       tda_reg("MAIN_DIV_BYTE_3    = 0x%02x\n", 0xff & regs[R_MD3]);
-
-       /* only dump extended regs if DBG_ADV is set */
-       if (!(tda18271_debug & DBG_ADV))
-               return;
-
-       /* W indicates write-only registers.
-        * Register dump for write-only registers shows last value written. */
-
-       tda_reg("EXTENDED_BYTE_1    = 0x%02x\n", 0xff & regs[R_EB1]);
-       tda_reg("EXTENDED_BYTE_2    = 0x%02x\n", 0xff & regs[R_EB2]);
-       tda_reg("EXTENDED_BYTE_3    = 0x%02x\n", 0xff & regs[R_EB3]);
-       tda_reg("EXTENDED_BYTE_4    = 0x%02x\n", 0xff & regs[R_EB4]);
-       tda_reg("EXTENDED_BYTE_5    = 0x%02x\n", 0xff & regs[R_EB5]);
-       tda_reg("EXTENDED_BYTE_6    = 0x%02x\n", 0xff & regs[R_EB6]);
-       tda_reg("EXTENDED_BYTE_7    = 0x%02x\n", 0xff & regs[R_EB7]);
-       tda_reg("EXTENDED_BYTE_8    = 0x%02x\n", 0xff & regs[R_EB8]);
-       tda_reg("EXTENDED_BYTE_9  W = 0x%02x\n", 0xff & regs[R_EB9]);
-       tda_reg("EXTENDED_BYTE_10   = 0x%02x\n", 0xff & regs[R_EB10]);
-       tda_reg("EXTENDED_BYTE_11   = 0x%02x\n", 0xff & regs[R_EB11]);
-       tda_reg("EXTENDED_BYTE_12   = 0x%02x\n", 0xff & regs[R_EB12]);
-       tda_reg("EXTENDED_BYTE_13   = 0x%02x\n", 0xff & regs[R_EB13]);
-       tda_reg("EXTENDED_BYTE_14   = 0x%02x\n", 0xff & regs[R_EB14]);
-       tda_reg("EXTENDED_BYTE_15   = 0x%02x\n", 0xff & regs[R_EB15]);
-       tda_reg("EXTENDED_BYTE_16 W = 0x%02x\n", 0xff & regs[R_EB16]);
-       tda_reg("EXTENDED_BYTE_17 W = 0x%02x\n", 0xff & regs[R_EB17]);
-       tda_reg("EXTENDED_BYTE_18   = 0x%02x\n", 0xff & regs[R_EB18]);
-       tda_reg("EXTENDED_BYTE_19 W = 0x%02x\n", 0xff & regs[R_EB19]);
-       tda_reg("EXTENDED_BYTE_20 W = 0x%02x\n", 0xff & regs[R_EB20]);
-       tda_reg("EXTENDED_BYTE_21   = 0x%02x\n", 0xff & regs[R_EB21]);
-       tda_reg("EXTENDED_BYTE_22   = 0x%02x\n", 0xff & regs[R_EB22]);
-       tda_reg("EXTENDED_BYTE_23   = 0x%02x\n", 0xff & regs[R_EB23]);
-}
-
-int tda18271_read_regs(struct dvb_frontend *fe)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       unsigned char buf = 0x00;
-       int ret;
-       struct i2c_msg msg[] = {
-               { .addr = priv->i2c_props.addr, .flags = 0,
-                 .buf = &buf, .len = 1 },
-               { .addr = priv->i2c_props.addr, .flags = I2C_M_RD,
-                 .buf = regs, .len = 16 }
-       };
-
-       tda18271_i2c_gate_ctrl(fe, 1);
-
-       /* read all registers */
-       ret = i2c_transfer(priv->i2c_props.adap, msg, 2);
-
-       tda18271_i2c_gate_ctrl(fe, 0);
-
-       if (ret != 2)
-               tda_err("ERROR: i2c_transfer returned: %d\n", ret);
-
-       if (tda18271_debug & DBG_REG)
-               tda18271_dump_regs(fe, 0);
-
-       return (ret == 2 ? 0 : ret);
-}
-
-int tda18271_read_extended(struct dvb_frontend *fe)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       unsigned char regdump[TDA18271_NUM_REGS];
-       unsigned char buf = 0x00;
-       int ret, i;
-       struct i2c_msg msg[] = {
-               { .addr = priv->i2c_props.addr, .flags = 0,
-                 .buf = &buf, .len = 1 },
-               { .addr = priv->i2c_props.addr, .flags = I2C_M_RD,
-                 .buf = regdump, .len = TDA18271_NUM_REGS }
-       };
-
-       tda18271_i2c_gate_ctrl(fe, 1);
-
-       /* read all registers */
-       ret = i2c_transfer(priv->i2c_props.adap, msg, 2);
-
-       tda18271_i2c_gate_ctrl(fe, 0);
-
-       if (ret != 2)
-               tda_err("ERROR: i2c_transfer returned: %d\n", ret);
-
-       for (i = 0; i < TDA18271_NUM_REGS; i++) {
-               /* don't update write-only registers */
-               if ((i != R_EB9)  &&
-                   (i != R_EB16) &&
-                   (i != R_EB17) &&
-                   (i != R_EB19) &&
-                   (i != R_EB20))
-               regs[i] = regdump[i];
-       }
-
-       if (tda18271_debug & DBG_REG)
-               tda18271_dump_regs(fe, 1);
-
-       return (ret == 2 ? 0 : ret);
-}
-
-int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       unsigned char buf[TDA18271_NUM_REGS + 1];
-       struct i2c_msg msg = { .addr = priv->i2c_props.addr, .flags = 0,
-                              .buf = buf };
-       int i, ret = 1, max;
-
-       BUG_ON((len == 0) || (idx + len > sizeof(buf)));
-
-
-       switch (priv->small_i2c) {
-       case TDA18271_03_BYTE_CHUNK_INIT:
-               max = 3;
-               break;
-       case TDA18271_08_BYTE_CHUNK_INIT:
-               max = 8;
-               break;
-       case TDA18271_16_BYTE_CHUNK_INIT:
-               max = 16;
-               break;
-       case TDA18271_39_BYTE_CHUNK_INIT:
-       default:
-               max = 39;
-       }
-
-       tda18271_i2c_gate_ctrl(fe, 1);
-       while (len) {
-               if (max > len)
-                       max = len;
-
-               buf[0] = idx;
-               for (i = 1; i <= max; i++)
-                       buf[i] = regs[idx - 1 + i];
-
-               msg.len = max + 1;
-
-               /* write registers */
-               ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
-               if (ret != 1)
-                       break;
-
-               idx += max;
-               len -= max;
-       }
-       tda18271_i2c_gate_ctrl(fe, 0);
-
-       if (ret != 1)
-               tda_err("ERROR: idx = 0x%x, len = %d, "
-                       "i2c_transfer returned: %d\n", idx, max, ret);
-
-       return (ret == 1 ? 0 : ret);
-}
-
-/*---------------------------------------------------------------------*/
-
-int tda18271_charge_pump_source(struct dvb_frontend *fe,
-                               enum tda18271_pll pll, int force)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-
-       int r_cp = (pll == TDA18271_CAL_PLL) ? R_EB7 : R_EB4;
-
-       regs[r_cp] &= ~0x20;
-       regs[r_cp] |= ((force & 1) << 5);
-
-       return tda18271_write_regs(fe, r_cp, 1);
-}
-
-int tda18271_init_regs(struct dvb_frontend *fe)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-
-       tda_dbg("initializing registers for device @ %d-%04x\n",
-               i2c_adapter_id(priv->i2c_props.adap),
-               priv->i2c_props.addr);
-
-       /* initialize registers */
-       switch (priv->id) {
-       case TDA18271HDC1:
-               regs[R_ID]   = 0x83;
-               break;
-       case TDA18271HDC2:
-               regs[R_ID]   = 0x84;
-               break;
-       };
-
-       regs[R_TM]   = 0x08;
-       regs[R_PL]   = 0x80;
-       regs[R_EP1]  = 0xc6;
-       regs[R_EP2]  = 0xdf;
-       regs[R_EP3]  = 0x16;
-       regs[R_EP4]  = 0x60;
-       regs[R_EP5]  = 0x80;
-       regs[R_CPD]  = 0x80;
-       regs[R_CD1]  = 0x00;
-       regs[R_CD2]  = 0x00;
-       regs[R_CD3]  = 0x00;
-       regs[R_MPD]  = 0x00;
-       regs[R_MD1]  = 0x00;
-       regs[R_MD2]  = 0x00;
-       regs[R_MD3]  = 0x00;
-
-       switch (priv->id) {
-       case TDA18271HDC1:
-               regs[R_EB1]  = 0xff;
-               break;
-       case TDA18271HDC2:
-               regs[R_EB1]  = 0xfc;
-               break;
-       };
-
-       regs[R_EB2]  = 0x01;
-       regs[R_EB3]  = 0x84;
-       regs[R_EB4]  = 0x41;
-       regs[R_EB5]  = 0x01;
-       regs[R_EB6]  = 0x84;
-       regs[R_EB7]  = 0x40;
-       regs[R_EB8]  = 0x07;
-       regs[R_EB9]  = 0x00;
-       regs[R_EB10] = 0x00;
-       regs[R_EB11] = 0x96;
-
-       switch (priv->id) {
-       case TDA18271HDC1:
-               regs[R_EB12] = 0x0f;
-               break;
-       case TDA18271HDC2:
-               regs[R_EB12] = 0x33;
-               break;
-       };
-
-       regs[R_EB13] = 0xc1;
-       regs[R_EB14] = 0x00;
-       regs[R_EB15] = 0x8f;
-       regs[R_EB16] = 0x00;
-       regs[R_EB17] = 0x00;
-
-       switch (priv->id) {
-       case TDA18271HDC1:
-               regs[R_EB18] = 0x00;
-               break;
-       case TDA18271HDC2:
-               regs[R_EB18] = 0x8c;
-               break;
-       };
-
-       regs[R_EB19] = 0x00;
-       regs[R_EB20] = 0x20;
-
-       switch (priv->id) {
-       case TDA18271HDC1:
-               regs[R_EB21] = 0x33;
-               break;
-       case TDA18271HDC2:
-               regs[R_EB21] = 0xb3;
-               break;
-       };
-
-       regs[R_EB22] = 0x48;
-       regs[R_EB23] = 0xb0;
-
-       tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS);
-
-       /* setup agc1 gain */
-       regs[R_EB17] = 0x00;
-       tda18271_write_regs(fe, R_EB17, 1);
-       regs[R_EB17] = 0x03;
-       tda18271_write_regs(fe, R_EB17, 1);
-       regs[R_EB17] = 0x43;
-       tda18271_write_regs(fe, R_EB17, 1);
-       regs[R_EB17] = 0x4c;
-       tda18271_write_regs(fe, R_EB17, 1);
-
-       /* setup agc2 gain */
-       if ((priv->id) == TDA18271HDC1) {
-               regs[R_EB20] = 0xa0;
-               tda18271_write_regs(fe, R_EB20, 1);
-               regs[R_EB20] = 0xa7;
-               tda18271_write_regs(fe, R_EB20, 1);
-               regs[R_EB20] = 0xe7;
-               tda18271_write_regs(fe, R_EB20, 1);
-               regs[R_EB20] = 0xec;
-               tda18271_write_regs(fe, R_EB20, 1);
-       }
-
-       /* image rejection calibration */
-
-       /* low-band */
-       regs[R_EP3] = 0x1f;
-       regs[R_EP4] = 0x66;
-       regs[R_EP5] = 0x81;
-       regs[R_CPD] = 0xcc;
-       regs[R_CD1] = 0x6c;
-       regs[R_CD2] = 0x00;
-       regs[R_CD3] = 0x00;
-       regs[R_MPD] = 0xcd;
-       regs[R_MD1] = 0x77;
-       regs[R_MD2] = 0x08;
-       regs[R_MD3] = 0x00;
-
-       tda18271_write_regs(fe, R_EP3, 11);
-
-       if ((priv->id) == TDA18271HDC2) {
-               /* main pll cp source on */
-               tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 1);
-               msleep(1);
-
-               /* main pll cp source off */
-               tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 0);
-       }
-
-       msleep(5); /* pll locking */
-
-       /* launch detector */
-       tda18271_write_regs(fe, R_EP1, 1);
-       msleep(5); /* wanted low measurement */
-
-       regs[R_EP5] = 0x85;
-       regs[R_CPD] = 0xcb;
-       regs[R_CD1] = 0x66;
-       regs[R_CD2] = 0x70;
-
-       tda18271_write_regs(fe, R_EP3, 7);
-       msleep(5); /* pll locking */
-
-       /* launch optimization algorithm */
-       tda18271_write_regs(fe, R_EP2, 1);
-       msleep(30); /* image low optimization completion */
-
-       /* mid-band */
-       regs[R_EP5] = 0x82;
-       regs[R_CPD] = 0xa8;
-       regs[R_CD2] = 0x00;
-       regs[R_MPD] = 0xa9;
-       regs[R_MD1] = 0x73;
-       regs[R_MD2] = 0x1a;
-
-       tda18271_write_regs(fe, R_EP3, 11);
-       msleep(5); /* pll locking */
-
-       /* launch detector */
-       tda18271_write_regs(fe, R_EP1, 1);
-       msleep(5); /* wanted mid measurement */
-
-       regs[R_EP5] = 0x86;
-       regs[R_CPD] = 0xa8;
-       regs[R_CD1] = 0x66;
-       regs[R_CD2] = 0xa0;
-
-       tda18271_write_regs(fe, R_EP3, 7);
-       msleep(5); /* pll locking */
-
-       /* launch optimization algorithm */
-       tda18271_write_regs(fe, R_EP2, 1);
-       msleep(30); /* image mid optimization completion */
-
-       /* high-band */
-       regs[R_EP5] = 0x83;
-       regs[R_CPD] = 0x98;
-       regs[R_CD1] = 0x65;
-       regs[R_CD2] = 0x00;
-       regs[R_MPD] = 0x99;
-       regs[R_MD1] = 0x71;
-       regs[R_MD2] = 0xcd;
-
-       tda18271_write_regs(fe, R_EP3, 11);
-       msleep(5); /* pll locking */
-
-       /* launch detector */
-       tda18271_write_regs(fe, R_EP1, 1);
-       msleep(5); /* wanted high measurement */
-
-       regs[R_EP5] = 0x87;
-       regs[R_CD1] = 0x65;
-       regs[R_CD2] = 0x50;
-
-       tda18271_write_regs(fe, R_EP3, 7);
-       msleep(5); /* pll locking */
-
-       /* launch optimization algorithm */
-       tda18271_write_regs(fe, R_EP2, 1);
-       msleep(30); /* image high optimization completion */
-
-       /* return to normal mode */
-       regs[R_EP4] = 0x64;
-       tda18271_write_regs(fe, R_EP4, 1);
-
-       /* synchronize */
-       tda18271_write_regs(fe, R_EP1, 1);
-
-       return 0;
-}
-
-/*---------------------------------------------------------------------*/
-
-/*
- *  Standby modes, EP3 [7:5]
- *
- *  | SM  || SM_LT || SM_XT || mode description
- *  |=====\\=======\\=======\\===================================
- *  |  0  ||   0   ||   0   || normal mode
- *  |-----||-------||-------||-----------------------------------
- *  |     ||       ||       || standby mode w/ slave tuner output
- *  |  1  ||   0   ||   0   || & loop thru & xtal oscillator on
- *  |-----||-------||-------||-----------------------------------
- *  |  1  ||   1   ||   0   || standby mode w/ xtal oscillator on
- *  |-----||-------||-------||-----------------------------------
- *  |  1  ||   1   ||   1   || power off
- *
- */
-
-int tda18271_set_standby_mode(struct dvb_frontend *fe,
-                             int sm, int sm_lt, int sm_xt)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-
-       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]  |= (sm    ? (1 << 7) : 0) |
-                       (sm_lt ? (1 << 6) : 0) |
-                       (sm_xt ? (1 << 5) : 0);
-
-       return tda18271_write_regs(fe, R_EP3, 1);
-}
-
-/*---------------------------------------------------------------------*/
-
-int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq)
-{
-       /* sets main post divider & divider bytes, but does not write them */
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       u8 d, pd;
-       u32 div;
-
-       int ret = tda18271_lookup_pll_map(fe, MAIN_PLL, &freq, &pd, &d);
-       if (tda_fail(ret))
-               goto fail;
-
-       regs[R_MPD]   = (0x7f & pd);
-
-       div =  ((d * (freq / 1000)) << 7) / 125;
-
-       regs[R_MD1]   = 0x7f & (div >> 16);
-       regs[R_MD2]   = 0xff & (div >> 8);
-       regs[R_MD3]   = 0xff & div;
-fail:
-       return ret;
-}
-
-int tda18271_calc_cal_pll(struct dvb_frontend *fe, u32 freq)
-{
-       /* sets cal post divider & divider bytes, but does not write them */
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       u8 d, pd;
-       u32 div;
-
-       int ret = tda18271_lookup_pll_map(fe, CAL_PLL, &freq, &pd, &d);
-       if (tda_fail(ret))
-               goto fail;
-
-       regs[R_CPD]   = pd;
-
-       div =  ((d * (freq / 1000)) << 7) / 125;
-
-       regs[R_CD1]   = 0x7f & (div >> 16);
-       regs[R_CD2]   = 0xff & (div >> 8);
-       regs[R_CD3]   = 0xff & div;
-fail:
-       return ret;
-}
-
-/*---------------------------------------------------------------------*/
-
-int tda18271_calc_bp_filter(struct dvb_frontend *fe, u32 *freq)
-{
-       /* sets bp filter bits, but does not write them */
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       u8 val;
-
-       int ret = tda18271_lookup_map(fe, BP_FILTER, freq, &val);
-       if (tda_fail(ret))
-               goto fail;
-
-       regs[R_EP1]  &= ~0x07; /* clear bp filter bits */
-       regs[R_EP1]  |= (0x07 & val);
-fail:
-       return ret;
-}
-
-int tda18271_calc_km(struct dvb_frontend *fe, u32 *freq)
-{
-       /* sets K & M bits, but does not write them */
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       u8 val;
-
-       int ret = tda18271_lookup_map(fe, RF_CAL_KMCO, freq, &val);
-       if (tda_fail(ret))
-               goto fail;
-
-       regs[R_EB13] &= ~0x7c; /* clear k & m bits */
-       regs[R_EB13] |= (0x7c & val);
-fail:
-       return ret;
-}
-
-int tda18271_calc_rf_band(struct dvb_frontend *fe, u32 *freq)
-{
-       /* sets rf band bits, but does not write them */
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       u8 val;
-
-       int ret = tda18271_lookup_map(fe, RF_BAND, freq, &val);
-       if (tda_fail(ret))
-               goto fail;
-
-       regs[R_EP2]  &= ~0xe0; /* clear rf band bits */
-       regs[R_EP2]  |= (0xe0 & (val << 5));
-fail:
-       return ret;
-}
-
-int tda18271_calc_gain_taper(struct dvb_frontend *fe, u32 *freq)
-{
-       /* sets gain taper bits, but does not write them */
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       u8 val;
-
-       int ret = tda18271_lookup_map(fe, GAIN_TAPER, freq, &val);
-       if (tda_fail(ret))
-               goto fail;
-
-       regs[R_EP2]  &= ~0x1f; /* clear gain taper bits */
-       regs[R_EP2]  |= (0x1f & val);
-fail:
-       return ret;
-}
-
-int tda18271_calc_ir_measure(struct dvb_frontend *fe, u32 *freq)
-{
-       /* sets IR Meas bits, but does not write them */
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       u8 val;
-
-       int ret = tda18271_lookup_map(fe, IR_MEASURE, freq, &val);
-       if (tda_fail(ret))
-               goto fail;
-
-       regs[R_EP5] &= ~0x07;
-       regs[R_EP5] |= (0x07 & val);
-fail:
-       return ret;
-}
-
-int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq)
-{
-       /* sets rf cal byte (RFC_Cprog), but does not write it */
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       u8 val;
-
-       int ret = tda18271_lookup_map(fe, RF_CAL, freq, &val);
-       /* The TDA18271HD/C1 rf_cal map lookup is expected to go out of range
-        * for frequencies above 61.1 MHz.  In these cases, the internal RF
-        * tracking filters calibration mechanism is used.
-        *
-        * There is no need to warn the user about this.
-        */
-       if (ret < 0)
-               goto fail;
-
-       regs[R_EB14] = val;
-fail:
-       return ret;
-}
-
-int _tda_printk(struct tda18271_priv *state, const char *level,
-               const char *func, const char *fmt, ...)
-{
-       struct va_format vaf;
-       va_list args;
-       int rtn;
-
-       va_start(args, fmt);
-
-       vaf.fmt = fmt;
-       vaf.va = &args;
-
-       if (state)
-               rtn = printk("%s%s: [%d-%04x|%c] %pV",
-                            level, func, i2c_adapter_id(state->i2c_props.adap),
-                            state->i2c_props.addr,
-                            (state->role == TDA18271_MASTER) ? 'M' : 'S',
-                            &vaf);
-       else
-               rtn = printk("%s%s: %pV", level, func, &vaf);
-
-       va_end(args);
-
-       return rtn;
-}
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
deleted file mode 100644 (file)
index 2e67f44..0000000
+++ /dev/null
@@ -1,1345 +0,0 @@
-/*
-    tda18271-fe.c - driver for the Philips / NXP TDA18271 silicon tuner
-
-    Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
-
-    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.
-*/
-
-#include <linux/delay.h>
-#include <linux/videodev2.h>
-#include "tda18271-priv.h"
-
-int tda18271_debug;
-module_param_named(debug, tda18271_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debug level "
-                "(info=1, map=2, reg=4, adv=8, cal=16 (or-able))");
-
-static int tda18271_cal_on_startup = -1;
-module_param_named(cal, tda18271_cal_on_startup, int, 0644);
-MODULE_PARM_DESC(cal, "perform RF tracking filter calibration on startup");
-
-static DEFINE_MUTEX(tda18271_list_mutex);
-static LIST_HEAD(hybrid_tuner_instance_list);
-
-/*---------------------------------------------------------------------*/
-
-static int tda18271_toggle_output(struct dvb_frontend *fe, int standby)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-
-       int ret = tda18271_set_standby_mode(fe, standby ? 1 : 0,
-                       priv->output_opt & TDA18271_OUTPUT_LT_OFF ? 1 : 0,
-                       priv->output_opt & TDA18271_OUTPUT_XT_OFF ? 1 : 0);
-
-       if (tda_fail(ret))
-               goto fail;
-
-       tda_dbg("%s mode: xtal oscillator %s, slave tuner loop thru %s\n",
-               standby ? "standby" : "active",
-               priv->output_opt & TDA18271_OUTPUT_XT_OFF ? "off" : "on",
-               priv->output_opt & TDA18271_OUTPUT_LT_OFF ? "off" : "on");
-fail:
-       return ret;
-}
-
-/*---------------------------------------------------------------------*/
-
-static inline int charge_pump_source(struct dvb_frontend *fe, int force)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       return tda18271_charge_pump_source(fe,
-                                          (priv->role == TDA18271_SLAVE) ?
-                                          TDA18271_CAL_PLL :
-                                          TDA18271_MAIN_PLL, force);
-}
-
-static inline void tda18271_set_if_notch(struct dvb_frontend *fe)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-
-       switch (priv->mode) {
-       case TDA18271_ANALOG:
-               regs[R_MPD]  &= ~0x80; /* IF notch = 0 */
-               break;
-       case TDA18271_DIGITAL:
-               regs[R_MPD]  |= 0x80; /* IF notch = 1 */
-               break;
-       }
-}
-
-static int tda18271_channel_configuration(struct dvb_frontend *fe,
-                                         struct tda18271_std_map_item *map,
-                                         u32 freq, u32 bw)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       int ret;
-       u32 N;
-
-       /* update TV broadcast parameters */
-
-       /* set standard */
-       regs[R_EP3]  &= ~0x1f; /* clear std bits */
-       regs[R_EP3]  |= (map->agc_mode << 3) | map->std;
-
-       if (priv->id == TDA18271HDC2) {
-               /* set rfagc to high speed mode */
-               regs[R_EP3] &= ~0x04;
-       }
-
-       /* set cal mode to normal */
-       regs[R_EP4]  &= ~0x03;
-
-       /* update IF output level */
-       regs[R_EP4]  &= ~0x1c; /* clear if level bits */
-       regs[R_EP4]  |= (map->if_lvl << 2);
-
-       /* update FM_RFn */
-       regs[R_EP4]  &= ~0x80;
-       regs[R_EP4]  |= map->fm_rfn << 7;
-
-       /* update rf top / if top */
-       regs[R_EB22]  = 0x00;
-       regs[R_EB22] |= map->rfagc_top;
-       ret = tda18271_write_regs(fe, R_EB22, 1);
-       if (tda_fail(ret))
-               goto fail;
-
-       /* --------------------------------------------------------------- */
-
-       /* disable Power Level Indicator */
-       regs[R_EP1]  |= 0x40;
-
-       /* make sure thermometer is off */
-       regs[R_TM]   &= ~0x10;
-
-       /* frequency dependent parameters */
-
-       tda18271_calc_ir_measure(fe, &freq);
-
-       tda18271_calc_bp_filter(fe, &freq);
-
-       tda18271_calc_rf_band(fe, &freq);
-
-       tda18271_calc_gain_taper(fe, &freq);
-
-       /* --------------------------------------------------------------- */
-
-       /* dual tuner and agc1 extra configuration */
-
-       switch (priv->role) {
-       case TDA18271_MASTER:
-               regs[R_EB1]  |= 0x04; /* main vco */
-               break;
-       case TDA18271_SLAVE:
-               regs[R_EB1]  &= ~0x04; /* cal vco */
-               break;
-       }
-
-       /* agc1 always active */
-       regs[R_EB1]  &= ~0x02;
-
-       /* agc1 has priority on agc2 */
-       regs[R_EB1]  &= ~0x01;
-
-       ret = tda18271_write_regs(fe, R_EB1, 1);
-       if (tda_fail(ret))
-               goto fail;
-
-       /* --------------------------------------------------------------- */
-
-       N = map->if_freq * 1000 + freq;
-
-       switch (priv->role) {
-       case TDA18271_MASTER:
-               tda18271_calc_main_pll(fe, N);
-               tda18271_set_if_notch(fe);
-               tda18271_write_regs(fe, R_MPD, 4);
-               break;
-       case TDA18271_SLAVE:
-               tda18271_calc_cal_pll(fe, N);
-               tda18271_write_regs(fe, R_CPD, 4);
-
-               regs[R_MPD] = regs[R_CPD] & 0x7f;
-               tda18271_set_if_notch(fe);
-               tda18271_write_regs(fe, R_MPD, 1);
-               break;
-       }
-
-       ret = tda18271_write_regs(fe, R_TM, 7);
-       if (tda_fail(ret))
-               goto fail;
-
-       /* force charge pump source */
-       charge_pump_source(fe, 1);
-
-       msleep(1);
-
-       /* return pll to normal operation */
-       charge_pump_source(fe, 0);
-
-       msleep(20);
-
-       if (priv->id == TDA18271HDC2) {
-               /* set rfagc to normal speed mode */
-               if (map->fm_rfn)
-                       regs[R_EP3] &= ~0x04;
-               else
-                       regs[R_EP3] |= 0x04;
-               ret = tda18271_write_regs(fe, R_EP3, 1);
-       }
-fail:
-       return ret;
-}
-
-static int tda18271_read_thermometer(struct dvb_frontend *fe)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       int tm;
-
-       /* switch thermometer on */
-       regs[R_TM]   |= 0x10;
-       tda18271_write_regs(fe, R_TM, 1);
-
-       /* read thermometer info */
-       tda18271_read_regs(fe);
-
-       if ((((regs[R_TM] & 0x0f) == 0x00) && ((regs[R_TM] & 0x20) == 0x20)) ||
-           (((regs[R_TM] & 0x0f) == 0x08) && ((regs[R_TM] & 0x20) == 0x00))) {
-
-               if ((regs[R_TM] & 0x20) == 0x20)
-                       regs[R_TM] &= ~0x20;
-               else
-                       regs[R_TM] |= 0x20;
-
-               tda18271_write_regs(fe, R_TM, 1);
-
-               msleep(10); /* temperature sensing */
-
-               /* read thermometer info */
-               tda18271_read_regs(fe);
-       }
-
-       tm = tda18271_lookup_thermometer(fe);
-
-       /* switch thermometer off */
-       regs[R_TM]   &= ~0x10;
-       tda18271_write_regs(fe, R_TM, 1);
-
-       /* set CAL mode to normal */
-       regs[R_EP4]  &= ~0x03;
-       tda18271_write_regs(fe, R_EP4, 1);
-
-       return tm;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
-                                                    u32 freq)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
-       unsigned char *regs = priv->tda18271_regs;
-       int i, ret;
-       u8 tm_current, dc_over_dt, rf_tab;
-       s32 rfcal_comp, approx;
-
-       /* power up */
-       ret = tda18271_set_standby_mode(fe, 0, 0, 0);
-       if (tda_fail(ret))
-               goto fail;
-
-       /* read die current temperature */
-       tm_current = tda18271_read_thermometer(fe);
-
-       /* frequency dependent parameters */
-
-       tda18271_calc_rf_cal(fe, &freq);
-       rf_tab = regs[R_EB14];
-
-       i = tda18271_lookup_rf_band(fe, &freq, NULL);
-       if (tda_fail(i))
-               return i;
-
-       if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) {
-               approx = map[i].rf_a1 * (s32)(freq / 1000 - map[i].rf1) +
-                       map[i].rf_b1 + rf_tab;
-       } else {
-               approx = map[i].rf_a2 * (s32)(freq / 1000 - map[i].rf2) +
-                       map[i].rf_b2 + rf_tab;
-       }
-
-       if (approx < 0)
-               approx = 0;
-       if (approx > 255)
-               approx = 255;
-
-       tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt);
-
-       /* calculate temperature compensation */
-       rfcal_comp = dc_over_dt * (s32)(tm_current - priv->tm_rfcal) / 1000;
-
-       regs[R_EB14] = (unsigned char)(approx + rfcal_comp);
-       ret = tda18271_write_regs(fe, R_EB14, 1);
-fail:
-       return ret;
-}
-
-static int tda18271_por(struct dvb_frontend *fe)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       int ret;
-
-       /* power up detector 1 */
-       regs[R_EB12] &= ~0x20;
-       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] &= ~0x03; /* set agc1_gain to  6 dB */
-       ret = tda18271_write_regs(fe, R_EB18, 1);
-       if (tda_fail(ret))
-               goto fail;
-
-       regs[R_EB21] |= 0x03; /* set agc2_gain to -6 dB */
-
-       /* POR mode */
-       ret = tda18271_set_standby_mode(fe, 1, 0, 0);
-       if (tda_fail(ret))
-               goto fail;
-
-       /* disable 1.5 MHz low pass filter */
-       regs[R_EB23] &= ~0x04; /* forcelp_fc2_en = 0 */
-       regs[R_EB23] &= ~0x02; /* XXX: lp_fc[2] = 0 */
-       ret = tda18271_write_regs(fe, R_EB21, 3);
-fail:
-       return ret;
-}
-
-static int tda18271_calibrate_rf(struct dvb_frontend *fe, u32 freq)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       u32 N;
-
-       /* set CAL mode to normal */
-       regs[R_EP4]  &= ~0x03;
-       tda18271_write_regs(fe, R_EP4, 1);
-
-       /* switch off agc1 */
-       regs[R_EP3]  |= 0x40; /* sm_lt = 1 */
-
-       regs[R_EB18] |= 0x03; /* set agc1_gain to 15 dB */
-       tda18271_write_regs(fe, R_EB18, 1);
-
-       /* frequency dependent parameters */
-
-       tda18271_calc_bp_filter(fe, &freq);
-       tda18271_calc_gain_taper(fe, &freq);
-       tda18271_calc_rf_band(fe, &freq);
-       tda18271_calc_km(fe, &freq);
-
-       tda18271_write_regs(fe, R_EP1, 3);
-       tda18271_write_regs(fe, R_EB13, 1);
-
-       /* main pll charge pump source */
-       tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 1);
-
-       /* cal pll charge pump source */
-       tda18271_charge_pump_source(fe, TDA18271_CAL_PLL, 1);
-
-       /* force dcdc converter to 0 V */
-       regs[R_EB14] = 0x00;
-       tda18271_write_regs(fe, R_EB14, 1);
-
-       /* disable plls lock */
-       regs[R_EB20] &= ~0x20;
-       tda18271_write_regs(fe, R_EB20, 1);
-
-       /* set CAL mode to RF tracking filter calibration */
-       regs[R_EP4]  |= 0x03;
-       tda18271_write_regs(fe, R_EP4, 2);
-
-       /* --------------------------------------------------------------- */
-
-       /* set the internal calibration signal */
-       N = freq;
-
-       tda18271_calc_cal_pll(fe, N);
-       tda18271_write_regs(fe, R_CPD, 4);
-
-       /* downconvert internal calibration */
-       N += 1000000;
-
-       tda18271_calc_main_pll(fe, N);
-       tda18271_write_regs(fe, R_MPD, 4);
-
-       msleep(5);
-
-       tda18271_write_regs(fe, R_EP2, 1);
-       tda18271_write_regs(fe, R_EP1, 1);
-       tda18271_write_regs(fe, R_EP2, 1);
-       tda18271_write_regs(fe, R_EP1, 1);
-
-       /* --------------------------------------------------------------- */
-
-       /* normal operation for the main pll */
-       tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 0);
-
-       /* normal operation for the cal pll  */
-       tda18271_charge_pump_source(fe, TDA18271_CAL_PLL, 0);
-
-       msleep(10); /* plls locking */
-
-       /* launch the rf tracking filters calibration */
-       regs[R_EB20]  |= 0x20;
-       tda18271_write_regs(fe, R_EB20, 1);
-
-       msleep(60); /* calibration */
-
-       /* --------------------------------------------------------------- */
-
-       /* set CAL mode to normal */
-       regs[R_EP4]  &= ~0x03;
-
-       /* switch on agc1 */
-       regs[R_EP3]  &= ~0x40; /* sm_lt = 0 */
-
-       regs[R_EB18] &= ~0x03; /* set agc1_gain to  6 dB */
-       tda18271_write_regs(fe, R_EB18, 1);
-
-       tda18271_write_regs(fe, R_EP3, 2);
-
-       /* synchronization */
-       tda18271_write_regs(fe, R_EP1, 1);
-
-       /* get calibration result */
-       tda18271_read_extended(fe);
-
-       return regs[R_EB14];
-}
-
-static int tda18271_powerscan(struct dvb_frontend *fe,
-                             u32 *freq_in, u32 *freq_out)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       int sgn, bcal, count, wait, ret;
-       u8 cid_target;
-       u16 count_limit;
-       u32 freq;
-
-       freq = *freq_in;
-
-       tda18271_calc_rf_band(fe, &freq);
-       tda18271_calc_rf_cal(fe, &freq);
-       tda18271_calc_gain_taper(fe, &freq);
-       tda18271_lookup_cid_target(fe, &freq, &cid_target, &count_limit);
-
-       tda18271_write_regs(fe, R_EP2, 1);
-       tda18271_write_regs(fe, R_EB14, 1);
-
-       /* downconvert frequency */
-       freq += 1000000;
-
-       tda18271_calc_main_pll(fe, freq);
-       tda18271_write_regs(fe, R_MPD, 4);
-
-       msleep(5); /* pll locking */
-
-       /* detection mode */
-       regs[R_EP4]  &= ~0x03;
-       regs[R_EP4]  |= 0x01;
-       tda18271_write_regs(fe, R_EP4, 1);
-
-       /* launch power detection measurement */
-       tda18271_write_regs(fe, R_EP2, 1);
-
-       /* read power detection info, stored in EB10 */
-       ret = tda18271_read_extended(fe);
-       if (tda_fail(ret))
-               return ret;
-
-       /* algorithm initialization */
-       sgn = 1;
-       *freq_out = *freq_in;
-       bcal = 0;
-       count = 0;
-       wait = false;
-
-       while ((regs[R_EB10] & 0x3f) < cid_target) {
-               /* downconvert updated freq to 1 MHz */
-               freq = *freq_in + (sgn * count) + 1000000;
-
-               tda18271_calc_main_pll(fe, freq);
-               tda18271_write_regs(fe, R_MPD, 4);
-
-               if (wait) {
-                       msleep(5); /* pll locking */
-                       wait = false;
-               } else
-                       udelay(100); /* pll locking */
-
-               /* launch power detection measurement */
-               tda18271_write_regs(fe, R_EP2, 1);
-
-               /* read power detection info, stored in EB10 */
-               ret = tda18271_read_extended(fe);
-               if (tda_fail(ret))
-                       return ret;
-
-               count += 200;
-
-               if (count <= count_limit)
-                       continue;
-
-               if (sgn <= 0)
-                       break;
-
-               sgn = -1 * sgn;
-               count = 200;
-               wait = true;
-       }
-
-       if ((regs[R_EB10] & 0x3f) >= cid_target) {
-               bcal = 1;
-               *freq_out = freq - 1000000;
-       } else
-               bcal = 0;
-
-       tda_cal("bcal = %d, freq_in = %d, freq_out = %d (freq = %d)\n",
-               bcal, *freq_in, *freq_out, freq);
-
-       return bcal;
-}
-
-static int tda18271_powerscan_init(struct dvb_frontend *fe)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       int ret;
-
-       /* set standard to digital */
-       regs[R_EP3]  &= ~0x1f; /* clear std bits */
-       regs[R_EP3]  |= 0x12;
-
-       /* set cal mode to normal */
-       regs[R_EP4]  &= ~0x03;
-
-       /* update IF output level */
-       regs[R_EP4]  &= ~0x1c; /* clear if level bits */
-
-       ret = tda18271_write_regs(fe, R_EP3, 2);
-       if (tda_fail(ret))
-               goto fail;
-
-       regs[R_EB18] &= ~0x03; /* set agc1_gain to   6 dB */
-       ret = tda18271_write_regs(fe, R_EB18, 1);
-       if (tda_fail(ret))
-               goto fail;
-
-       regs[R_EB21] &= ~0x03; /* set agc2_gain to -15 dB */
-
-       /* 1.5 MHz low pass filter */
-       regs[R_EB23] |= 0x04; /* forcelp_fc2_en = 1 */
-       regs[R_EB23] |= 0x02; /* lp_fc[2] = 1 */
-
-       ret = tda18271_write_regs(fe, R_EB21, 3);
-fail:
-       return ret;
-}
-
-static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
-       unsigned char *regs = priv->tda18271_regs;
-       int bcal, rf, i;
-       s32 divisor, dividend;
-#define RF1 0
-#define RF2 1
-#define RF3 2
-       u32 rf_default[3];
-       u32 rf_freq[3];
-       s32 prog_cal[3];
-       s32 prog_tab[3];
-
-       i = tda18271_lookup_rf_band(fe, &freq, NULL);
-
-       if (tda_fail(i))
-               return i;
-
-       rf_default[RF1] = 1000 * map[i].rf1_def;
-       rf_default[RF2] = 1000 * map[i].rf2_def;
-       rf_default[RF3] = 1000 * map[i].rf3_def;
-
-       for (rf = RF1; rf <= RF3; rf++) {
-               if (0 == rf_default[rf])
-                       return 0;
-               tda_cal("freq = %d, rf = %d\n", freq, rf);
-
-               /* look for optimized calibration frequency */
-               bcal = tda18271_powerscan(fe, &rf_default[rf], &rf_freq[rf]);
-               if (tda_fail(bcal))
-                       return bcal;
-
-               tda18271_calc_rf_cal(fe, &rf_freq[rf]);
-               prog_tab[rf] = (s32)regs[R_EB14];
-
-               if (1 == bcal)
-                       prog_cal[rf] =
-                               (s32)tda18271_calibrate_rf(fe, rf_freq[rf]);
-               else
-                       prog_cal[rf] = prog_tab[rf];
-
-               switch (rf) {
-               case RF1:
-                       map[i].rf_a1 = 0;
-                       map[i].rf_b1 = (prog_cal[RF1] - prog_tab[RF1]);
-                       map[i].rf1   = rf_freq[RF1] / 1000;
-                       break;
-               case RF2:
-                       dividend = (prog_cal[RF2] - prog_tab[RF2] -
-                                   prog_cal[RF1] + prog_tab[RF1]);
-                       divisor = (s32)(rf_freq[RF2] - rf_freq[RF1]) / 1000;
-                       map[i].rf_a1 = (dividend / divisor);
-                       map[i].rf2   = rf_freq[RF2] / 1000;
-                       break;
-               case RF3:
-                       dividend = (prog_cal[RF3] - prog_tab[RF3] -
-                                   prog_cal[RF2] + prog_tab[RF2]);
-                       divisor = (s32)(rf_freq[RF3] - rf_freq[RF2]) / 1000;
-                       map[i].rf_a2 = (dividend / divisor);
-                       map[i].rf_b2 = (prog_cal[RF2] - prog_tab[RF2]);
-                       map[i].rf3   = rf_freq[RF3] / 1000;
-                       break;
-               default:
-                       BUG();
-               }
-       }
-
-       return 0;
-}
-
-static int tda18271_calc_rf_filter_curve(struct dvb_frontend *fe)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned int i;
-       int ret;
-
-       tda_info("tda18271: performing RF tracking filter calibration\n");
-
-       /* wait for die temperature stabilization */
-       msleep(200);
-
-       ret = tda18271_powerscan_init(fe);
-       if (tda_fail(ret))
-               goto fail;
-
-       /* rf band calibration */
-       for (i = 0; priv->rf_cal_state[i].rfmax != 0; i++) {
-               ret =
-               tda18271_rf_tracking_filters_init(fe, 1000 *
-                                                 priv->rf_cal_state[i].rfmax);
-               if (tda_fail(ret))
-                       goto fail;
-       }
-
-       priv->tm_rfcal = tda18271_read_thermometer(fe);
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int tda18271c2_rf_cal_init(struct dvb_frontend *fe)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       int ret;
-
-       /* test RF_CAL_OK to see if we need init */
-       if ((regs[R_EP1] & 0x10) == 0)
-               priv->cal_initialized = false;
-
-       if (priv->cal_initialized)
-               return 0;
-
-       ret = tda18271_calc_rf_filter_curve(fe);
-       if (tda_fail(ret))
-               goto fail;
-
-       ret = tda18271_por(fe);
-       if (tda_fail(ret))
-               goto fail;
-
-       tda_info("tda18271: RF tracking filter calibration complete\n");
-
-       priv->cal_initialized = true;
-       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,
-                                                    u32 freq, u32 bw)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       int ret;
-       u32 N = 0;
-
-       /* calculate bp filter */
-       tda18271_calc_bp_filter(fe, &freq);
-       tda18271_write_regs(fe, R_EP1, 1);
-
-       regs[R_EB4]  &= 0x07;
-       regs[R_EB4]  |= 0x60;
-       tda18271_write_regs(fe, R_EB4, 1);
-
-       regs[R_EB7]   = 0x60;
-       tda18271_write_regs(fe, R_EB7, 1);
-
-       regs[R_EB14]  = 0x00;
-       tda18271_write_regs(fe, R_EB14, 1);
-
-       regs[R_EB20]  = 0xcc;
-       tda18271_write_regs(fe, R_EB20, 1);
-
-       /* set cal mode to RF tracking filter calibration */
-       regs[R_EP4]  |= 0x03;
-
-       /* calculate cal pll */
-
-       switch (priv->mode) {
-       case TDA18271_ANALOG:
-               N = freq - 1250000;
-               break;
-       case TDA18271_DIGITAL:
-               N = freq + bw / 2;
-               break;
-       }
-
-       tda18271_calc_cal_pll(fe, N);
-
-       /* calculate main pll */
-
-       switch (priv->mode) {
-       case TDA18271_ANALOG:
-               N = freq - 250000;
-               break;
-       case TDA18271_DIGITAL:
-               N = freq + bw / 2 + 1000000;
-               break;
-       }
-
-       tda18271_calc_main_pll(fe, N);
-
-       ret = tda18271_write_regs(fe, R_EP3, 11);
-       if (tda_fail(ret))
-               return ret;
-
-       msleep(5); /* RF tracking filter calibration initialization */
-
-       /* search for K,M,CO for RF calibration */
-       tda18271_calc_km(fe, &freq);
-       tda18271_write_regs(fe, R_EB13, 1);
-
-       /* search for rf band */
-       tda18271_calc_rf_band(fe, &freq);
-
-       /* search for gain taper */
-       tda18271_calc_gain_taper(fe, &freq);
-
-       tda18271_write_regs(fe, R_EP2, 1);
-       tda18271_write_regs(fe, R_EP1, 1);
-       tda18271_write_regs(fe, R_EP2, 1);
-       tda18271_write_regs(fe, R_EP1, 1);
-
-       regs[R_EB4]  &= 0x07;
-       regs[R_EB4]  |= 0x40;
-       tda18271_write_regs(fe, R_EB4, 1);
-
-       regs[R_EB7]   = 0x40;
-       tda18271_write_regs(fe, R_EB7, 1);
-       msleep(10); /* pll locking */
-
-       regs[R_EB20]  = 0xec;
-       tda18271_write_regs(fe, R_EB20, 1);
-       msleep(60); /* RF tracking filter calibration completion */
-
-       regs[R_EP4]  &= ~0x03; /* set cal mode to normal */
-       tda18271_write_regs(fe, R_EP4, 1);
-
-       tda18271_write_regs(fe, R_EP1, 1);
-
-       /* RF tracking filter correction for VHF_Low band */
-       if (0 == tda18271_calc_rf_cal(fe, &freq))
-               tda18271_write_regs(fe, R_EB14, 1);
-
-       return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int tda18271_ir_cal_init(struct dvb_frontend *fe)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       int ret;
-
-       ret = tda18271_read_regs(fe);
-       if (tda_fail(ret))
-               goto fail;
-
-       /* test IR_CAL_OK to see if we need init */
-       if ((regs[R_EP1] & 0x08) == 0)
-               ret = tda18271_init_regs(fe);
-fail:
-       return ret;
-}
-
-static int tda18271_init(struct dvb_frontend *fe)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       int ret;
-
-       mutex_lock(&priv->lock);
-
-       /* full power up */
-       ret = tda18271_set_standby_mode(fe, 0, 0, 0);
-       if (tda_fail(ret))
-               goto fail;
-
-       /* initialization */
-       ret = tda18271_ir_cal_init(fe);
-       if (tda_fail(ret))
-               goto fail;
-
-       if (priv->id == TDA18271HDC2)
-               tda18271c2_rf_cal_init(fe);
-fail:
-       mutex_unlock(&priv->lock);
-
-       return ret;
-}
-
-static int tda18271_sleep(struct dvb_frontend *fe)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       int ret;
-
-       mutex_lock(&priv->lock);
-
-       /* enter standby mode, with required output features enabled */
-       ret = tda18271_toggle_output(fe, 1);
-
-       mutex_unlock(&priv->lock);
-
-       return ret;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int tda18271_agc(struct dvb_frontend *fe)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       int ret = 0;
-
-       switch (priv->config) {
-       case 0:
-               /* no external agc configuration required */
-               if (tda18271_debug & DBG_ADV)
-                       tda_dbg("no agc configuration provided\n");
-               break;
-       case 3:
-               /* switch with GPIO of saa713x */
-               tda_dbg("invoking callback\n");
-               if (fe->callback)
-                       ret = fe->callback(priv->i2c_props.adap->algo_data,
-                                          DVB_FRONTEND_COMPONENT_TUNER,
-                                          TDA18271_CALLBACK_CMD_AGC_ENABLE,
-                                          priv->mode);
-               break;
-       case 1:
-       case 2:
-       default:
-               /* n/a - currently not supported */
-               tda_err("unsupported configuration: %d\n", priv->config);
-               ret = -EINVAL;
-               break;
-       }
-       return ret;
-}
-
-static int tda18271_tune(struct dvb_frontend *fe,
-                        struct tda18271_std_map_item *map, u32 freq, u32 bw)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       int ret;
-
-       tda_dbg("freq = %d, ifc = %d, bw = %d, agc_mode = %d, std = %d\n",
-               freq, map->if_freq, bw, map->agc_mode, map->std);
-
-       ret = tda18271_agc(fe);
-       if (tda_fail(ret))
-               tda_warn("failed to configure agc\n");
-
-       ret = tda18271_init(fe);
-       if (tda_fail(ret))
-               goto fail;
-
-       mutex_lock(&priv->lock);
-
-       switch (priv->id) {
-       case TDA18271HDC1:
-               tda18271c1_rf_tracking_filter_calibration(fe, freq, bw);
-               break;
-       case TDA18271HDC2:
-               tda18271c2_rf_tracking_filters_correction(fe, freq);
-               break;
-       }
-       ret = tda18271_channel_configuration(fe, map, freq, bw);
-
-       mutex_unlock(&priv->lock);
-fail:
-       return ret;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int tda18271_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u32 delsys = c->delivery_system;
-       u32 bw = c->bandwidth_hz;
-       u32 freq = c->frequency;
-       struct tda18271_priv *priv = fe->tuner_priv;
-       struct tda18271_std_map *std_map = &priv->std;
-       struct tda18271_std_map_item *map;
-       int ret;
-
-       priv->mode = TDA18271_DIGITAL;
-
-       switch (delsys) {
-       case SYS_ATSC:
-               map = &std_map->atsc_6;
-               bw = 6000000;
-               break;
-       case SYS_ISDBT:
-       case SYS_DVBT:
-       case SYS_DVBT2:
-               if (bw <= 6000000) {
-                       map = &std_map->dvbt_6;
-               } else if (bw <= 7000000) {
-                       map = &std_map->dvbt_7;
-               } else {
-                       map = &std_map->dvbt_8;
-               }
-               break;
-       case SYS_DVBC_ANNEX_B:
-               bw = 6000000;
-               /* falltrough */
-       case SYS_DVBC_ANNEX_A:
-       case SYS_DVBC_ANNEX_C:
-               if (bw <= 6000000) {
-                       map = &std_map->qam_6;
-               } else if (bw <= 7000000) {
-                       map = &std_map->qam_7;
-               } else {
-                       map = &std_map->qam_8;
-               }
-               break;
-       default:
-               tda_warn("modulation type not supported!\n");
-               return -EINVAL;
-       }
-
-       /* When tuning digital, the analog demod must be tri-stated */
-       if (fe->ops.analog_ops.standby)
-               fe->ops.analog_ops.standby(fe);
-
-       ret = tda18271_tune(fe, map, freq, bw);
-
-       if (tda_fail(ret))
-               goto fail;
-
-       priv->if_freq   = map->if_freq;
-       priv->frequency = freq;
-       priv->bandwidth = bw;
-fail:
-       return ret;
-}
-
-static int tda18271_set_analog_params(struct dvb_frontend *fe,
-                                     struct analog_parameters *params)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       struct tda18271_std_map *std_map = &priv->std;
-       struct tda18271_std_map_item *map;
-       char *mode;
-       int ret;
-       u32 freq = params->frequency * 125 *
-               ((params->mode == V4L2_TUNER_RADIO) ? 1 : 1000) / 2;
-
-       priv->mode = TDA18271_ANALOG;
-
-       if (params->mode == V4L2_TUNER_RADIO) {
-               map = &std_map->fm_radio;
-               mode = "fm";
-       } else if (params->std & V4L2_STD_MN) {
-               map = &std_map->atv_mn;
-               mode = "MN";
-       } else if (params->std & V4L2_STD_B) {
-               map = &std_map->atv_b;
-               mode = "B";
-       } else if (params->std & V4L2_STD_GH) {
-               map = &std_map->atv_gh;
-               mode = "GH";
-       } else if (params->std & V4L2_STD_PAL_I) {
-               map = &std_map->atv_i;
-               mode = "I";
-       } else if (params->std & V4L2_STD_DK) {
-               map = &std_map->atv_dk;
-               mode = "DK";
-       } else if (params->std & V4L2_STD_SECAM_L) {
-               map = &std_map->atv_l;
-               mode = "L";
-       } else if (params->std & V4L2_STD_SECAM_LC) {
-               map = &std_map->atv_lc;
-               mode = "L'";
-       } else {
-               map = &std_map->atv_i;
-               mode = "xx";
-       }
-
-       tda_dbg("setting tda18271 to system %s\n", mode);
-
-       ret = tda18271_tune(fe, map, freq, 0);
-
-       if (tda_fail(ret))
-               goto fail;
-
-       priv->if_freq   = map->if_freq;
-       priv->frequency = freq;
-       priv->bandwidth = 0;
-fail:
-       return ret;
-}
-
-static int tda18271_release(struct dvb_frontend *fe)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-
-       mutex_lock(&tda18271_list_mutex);
-
-       if (priv)
-               hybrid_tuner_release_state(priv);
-
-       mutex_unlock(&tda18271_list_mutex);
-
-       fe->tuner_priv = NULL;
-
-       return 0;
-}
-
-static int tda18271_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       *frequency = priv->frequency;
-       return 0;
-}
-
-static int tda18271_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       *bandwidth = priv->bandwidth;
-       return 0;
-}
-
-static int tda18271_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       *frequency = (u32)priv->if_freq * 1000;
-       return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-#define tda18271_update_std(std_cfg, name) do {                                \
-       if (map->std_cfg.if_freq +                                      \
-               map->std_cfg.agc_mode + map->std_cfg.std +              \
-               map->std_cfg.if_lvl + map->std_cfg.rfagc_top > 0) {     \
-               tda_dbg("Using custom std config for %s\n", name);      \
-               memcpy(&std->std_cfg, &map->std_cfg,                    \
-                       sizeof(struct tda18271_std_map_item));          \
-       } } while (0)
-
-#define tda18271_dump_std_item(std_cfg, name) do {                     \
-       tda_dbg("(%s) if_freq = %d, agc_mode = %d, std = %d, "          \
-               "if_lvl = %d, rfagc_top = 0x%02x\n",                    \
-               name, std->std_cfg.if_freq,                             \
-               std->std_cfg.agc_mode, std->std_cfg.std,                \
-               std->std_cfg.if_lvl, std->std_cfg.rfagc_top);           \
-       } while (0)
-
-static int tda18271_dump_std_map(struct dvb_frontend *fe)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       struct tda18271_std_map *std = &priv->std;
-
-       tda_dbg("========== STANDARD MAP SETTINGS ==========\n");
-       tda18271_dump_std_item(fm_radio, "  fm  ");
-       tda18271_dump_std_item(atv_b,  "atv b ");
-       tda18271_dump_std_item(atv_dk, "atv dk");
-       tda18271_dump_std_item(atv_gh, "atv gh");
-       tda18271_dump_std_item(atv_i,  "atv i ");
-       tda18271_dump_std_item(atv_l,  "atv l ");
-       tda18271_dump_std_item(atv_lc, "atv l'");
-       tda18271_dump_std_item(atv_mn, "atv mn");
-       tda18271_dump_std_item(atsc_6, "atsc 6");
-       tda18271_dump_std_item(dvbt_6, "dvbt 6");
-       tda18271_dump_std_item(dvbt_7, "dvbt 7");
-       tda18271_dump_std_item(dvbt_8, "dvbt 8");
-       tda18271_dump_std_item(qam_6,  "qam 6 ");
-       tda18271_dump_std_item(qam_8,  "qam 8 ");
-
-       return 0;
-}
-
-static int tda18271_update_std_map(struct dvb_frontend *fe,
-                                  struct tda18271_std_map *map)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       struct tda18271_std_map *std = &priv->std;
-
-       if (!map)
-               return -EINVAL;
-
-       tda18271_update_std(fm_radio, "fm");
-       tda18271_update_std(atv_b,  "atv b");
-       tda18271_update_std(atv_dk, "atv dk");
-       tda18271_update_std(atv_gh, "atv gh");
-       tda18271_update_std(atv_i,  "atv i");
-       tda18271_update_std(atv_l,  "atv l");
-       tda18271_update_std(atv_lc, "atv l'");
-       tda18271_update_std(atv_mn, "atv mn");
-       tda18271_update_std(atsc_6, "atsc 6");
-       tda18271_update_std(dvbt_6, "dvbt 6");
-       tda18271_update_std(dvbt_7, "dvbt 7");
-       tda18271_update_std(dvbt_8, "dvbt 8");
-       tda18271_update_std(qam_6,  "qam 6");
-       tda18271_update_std(qam_8,  "qam 8");
-
-       return 0;
-}
-
-static int tda18271_get_id(struct dvb_frontend *fe)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       char *name;
-
-       mutex_lock(&priv->lock);
-       tda18271_read_regs(fe);
-       mutex_unlock(&priv->lock);
-
-       switch (regs[R_ID] & 0x7f) {
-       case 3:
-               name = "TDA18271HD/C1";
-               priv->id = TDA18271HDC1;
-               break;
-       case 4:
-               name = "TDA18271HD/C2";
-               priv->id = TDA18271HDC2;
-               break;
-       default:
-               tda_info("Unknown device (%i) detected @ %d-%04x, device not supported.\n",
-                        regs[R_ID], i2c_adapter_id(priv->i2c_props.adap),
-                        priv->i2c_props.addr);
-               return -EINVAL;
-       }
-
-       tda_info("%s detected @ %d-%04x\n", name,
-                i2c_adapter_id(priv->i2c_props.adap), priv->i2c_props.addr);
-
-       return 0;
-}
-
-static int tda18271_setup_configuration(struct dvb_frontend *fe,
-                                       struct tda18271_config *cfg)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-
-       priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
-       priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
-       priv->config = (cfg) ? cfg->config : 0;
-       priv->small_i2c = (cfg) ?
-               cfg->small_i2c : TDA18271_39_BYTE_CHUNK_INIT;
-       priv->output_opt = (cfg) ?
-               cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON;
-
-       return 0;
-}
-
-static inline int tda18271_need_cal_on_startup(struct tda18271_config *cfg)
-{
-       /* tda18271_cal_on_startup == -1 when cal module option is unset */
-       return ((tda18271_cal_on_startup == -1) ?
-               /* honor configuration setting */
-               ((cfg) && (cfg->rf_cal_on_startup)) :
-               /* module option overrides configuration setting */
-               (tda18271_cal_on_startup)) ? 1 : 0;
-}
-
-static int tda18271_set_config(struct dvb_frontend *fe, void *priv_cfg)
-{
-       struct tda18271_config *cfg = (struct tda18271_config *) priv_cfg;
-
-       tda18271_setup_configuration(fe, cfg);
-
-       if (tda18271_need_cal_on_startup(cfg))
-               tda18271_init(fe);
-
-       /* override default std map with values in config struct */
-       if ((cfg) && (cfg->std_map))
-               tda18271_update_std_map(fe, cfg->std_map);
-
-       return 0;
-}
-
-static const struct dvb_tuner_ops tda18271_tuner_ops = {
-       .info = {
-               .name = "NXP TDA18271HD",
-               .frequency_min  =  45000000,
-               .frequency_max  = 864000000,
-               .frequency_step =     62500
-       },
-       .init              = tda18271_init,
-       .sleep             = tda18271_sleep,
-       .set_params        = tda18271_set_params,
-       .set_analog_params = tda18271_set_analog_params,
-       .release           = tda18271_release,
-       .set_config        = tda18271_set_config,
-       .get_frequency     = tda18271_get_frequency,
-       .get_bandwidth     = tda18271_get_bandwidth,
-       .get_if_frequency  = tda18271_get_if_frequency,
-};
-
-struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
-                                    struct i2c_adapter *i2c,
-                                    struct tda18271_config *cfg)
-{
-       struct tda18271_priv *priv = NULL;
-       int instance, ret;
-
-       mutex_lock(&tda18271_list_mutex);
-
-       instance = hybrid_tuner_request_state(struct tda18271_priv, priv,
-                                             hybrid_tuner_instance_list,
-                                             i2c, addr, "tda18271");
-       switch (instance) {
-       case 0:
-               goto fail;
-       case 1:
-               /* new tuner instance */
-               fe->tuner_priv = priv;
-
-               tda18271_setup_configuration(fe, cfg);
-
-               priv->cal_initialized = false;
-               mutex_init(&priv->lock);
-
-               ret = tda18271_get_id(fe);
-               if (tda_fail(ret))
-                       goto fail;
-
-               ret = tda18271_assign_map_layout(fe);
-               if (tda_fail(ret))
-                       goto fail;
-
-               mutex_lock(&priv->lock);
-               tda18271_init_regs(fe);
-
-               if ((tda18271_need_cal_on_startup(cfg)) &&
-                   (priv->id == TDA18271HDC2))
-                       tda18271c2_rf_cal_init(fe);
-
-               mutex_unlock(&priv->lock);
-               break;
-       default:
-               /* existing tuner instance */
-               fe->tuner_priv = priv;
-
-               /* allow dvb driver to override configuration settings */
-               if (cfg) {
-                       if (cfg->gate != TDA18271_GATE_ANALOG)
-                               priv->gate = cfg->gate;
-                       if (cfg->role)
-                               priv->role = cfg->role;
-                       if (cfg->config)
-                               priv->config = cfg->config;
-                       if (cfg->small_i2c)
-                               priv->small_i2c = cfg->small_i2c;
-                       if (cfg->output_opt)
-                               priv->output_opt = cfg->output_opt;
-                       if (cfg->std_map)
-                               tda18271_update_std_map(fe, cfg->std_map);
-               }
-               if (tda18271_need_cal_on_startup(cfg))
-                       tda18271_init(fe);
-               break;
-       }
-
-       /* override default std map with values in config struct */
-       if ((cfg) && (cfg->std_map))
-               tda18271_update_std_map(fe, cfg->std_map);
-
-       mutex_unlock(&tda18271_list_mutex);
-
-       memcpy(&fe->ops.tuner_ops, &tda18271_tuner_ops,
-              sizeof(struct dvb_tuner_ops));
-
-       if (tda18271_debug & (DBG_MAP | DBG_ADV))
-               tda18271_dump_std_map(fe);
-
-       return fe;
-fail:
-       mutex_unlock(&tda18271_list_mutex);
-
-       tda18271_release(fe);
-       return NULL;
-}
-EXPORT_SYMBOL_GPL(tda18271_attach);
-MODULE_DESCRIPTION("NXP TDA18271HD analog / digital tuner driver");
-MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.4");
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/common/tuners/tda18271-maps.c b/drivers/media/common/tuners/tda18271-maps.c
deleted file mode 100644 (file)
index fb881c6..0000000
+++ /dev/null
@@ -1,1317 +0,0 @@
-/*
-    tda18271-maps.c - driver for the Philips / NXP TDA18271 silicon tuner
-
-    Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
-
-    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.
-*/
-
-#include "tda18271-priv.h"
-
-struct tda18271_pll_map {
-       u32 lomax;
-       u8 pd; /* post div */
-       u8 d;  /*      div */
-};
-
-struct tda18271_map {
-       u32 rfmax;
-       u8  val;
-};
-
-/*---------------------------------------------------------------------*/
-
-static struct tda18271_pll_map tda18271c1_main_pll[] = {
-       { .lomax =  32000, .pd = 0x5f, .d = 0xf0 },
-       { .lomax =  35000, .pd = 0x5e, .d = 0xe0 },
-       { .lomax =  37000, .pd = 0x5d, .d = 0xd0 },
-       { .lomax =  41000, .pd = 0x5c, .d = 0xc0 },
-       { .lomax =  44000, .pd = 0x5b, .d = 0xb0 },
-       { .lomax =  49000, .pd = 0x5a, .d = 0xa0 },
-       { .lomax =  54000, .pd = 0x59, .d = 0x90 },
-       { .lomax =  61000, .pd = 0x58, .d = 0x80 },
-       { .lomax =  65000, .pd = 0x4f, .d = 0x78 },
-       { .lomax =  70000, .pd = 0x4e, .d = 0x70 },
-       { .lomax =  75000, .pd = 0x4d, .d = 0x68 },
-       { .lomax =  82000, .pd = 0x4c, .d = 0x60 },
-       { .lomax =  89000, .pd = 0x4b, .d = 0x58 },
-       { .lomax =  98000, .pd = 0x4a, .d = 0x50 },
-       { .lomax = 109000, .pd = 0x49, .d = 0x48 },
-       { .lomax = 123000, .pd = 0x48, .d = 0x40 },
-       { .lomax = 131000, .pd = 0x3f, .d = 0x3c },
-       { .lomax = 141000, .pd = 0x3e, .d = 0x38 },
-       { .lomax = 151000, .pd = 0x3d, .d = 0x34 },
-       { .lomax = 164000, .pd = 0x3c, .d = 0x30 },
-       { .lomax = 179000, .pd = 0x3b, .d = 0x2c },
-       { .lomax = 197000, .pd = 0x3a, .d = 0x28 },
-       { .lomax = 219000, .pd = 0x39, .d = 0x24 },
-       { .lomax = 246000, .pd = 0x38, .d = 0x20 },
-       { .lomax = 263000, .pd = 0x2f, .d = 0x1e },
-       { .lomax = 282000, .pd = 0x2e, .d = 0x1c },
-       { .lomax = 303000, .pd = 0x2d, .d = 0x1a },
-       { .lomax = 329000, .pd = 0x2c, .d = 0x18 },
-       { .lomax = 359000, .pd = 0x2b, .d = 0x16 },
-       { .lomax = 395000, .pd = 0x2a, .d = 0x14 },
-       { .lomax = 438000, .pd = 0x29, .d = 0x12 },
-       { .lomax = 493000, .pd = 0x28, .d = 0x10 },
-       { .lomax = 526000, .pd = 0x1f, .d = 0x0f },
-       { .lomax = 564000, .pd = 0x1e, .d = 0x0e },
-       { .lomax = 607000, .pd = 0x1d, .d = 0x0d },
-       { .lomax = 658000, .pd = 0x1c, .d = 0x0c },
-       { .lomax = 718000, .pd = 0x1b, .d = 0x0b },
-       { .lomax = 790000, .pd = 0x1a, .d = 0x0a },
-       { .lomax = 877000, .pd = 0x19, .d = 0x09 },
-       { .lomax = 987000, .pd = 0x18, .d = 0x08 },
-       { .lomax =      0, .pd = 0x00, .d = 0x00 }, /* end */
-};
-
-static struct tda18271_pll_map tda18271c2_main_pll[] = {
-       { .lomax =  33125, .pd = 0x57, .d = 0xf0 },
-       { .lomax =  35500, .pd = 0x56, .d = 0xe0 },
-       { .lomax =  38188, .pd = 0x55, .d = 0xd0 },
-       { .lomax =  41375, .pd = 0x54, .d = 0xc0 },
-       { .lomax =  45125, .pd = 0x53, .d = 0xb0 },
-       { .lomax =  49688, .pd = 0x52, .d = 0xa0 },
-       { .lomax =  55188, .pd = 0x51, .d = 0x90 },
-       { .lomax =  62125, .pd = 0x50, .d = 0x80 },
-       { .lomax =  66250, .pd = 0x47, .d = 0x78 },
-       { .lomax =  71000, .pd = 0x46, .d = 0x70 },
-       { .lomax =  76375, .pd = 0x45, .d = 0x68 },
-       { .lomax =  82750, .pd = 0x44, .d = 0x60 },
-       { .lomax =  90250, .pd = 0x43, .d = 0x58 },
-       { .lomax =  99375, .pd = 0x42, .d = 0x50 },
-       { .lomax = 110375, .pd = 0x41, .d = 0x48 },
-       { .lomax = 124250, .pd = 0x40, .d = 0x40 },
-       { .lomax = 132500, .pd = 0x37, .d = 0x3c },
-       { .lomax = 142000, .pd = 0x36, .d = 0x38 },
-       { .lomax = 152750, .pd = 0x35, .d = 0x34 },
-       { .lomax = 165500, .pd = 0x34, .d = 0x30 },
-       { .lomax = 180500, .pd = 0x33, .d = 0x2c },
-       { .lomax = 198750, .pd = 0x32, .d = 0x28 },
-       { .lomax = 220750, .pd = 0x31, .d = 0x24 },
-       { .lomax = 248500, .pd = 0x30, .d = 0x20 },
-       { .lomax = 265000, .pd = 0x27, .d = 0x1e },
-       { .lomax = 284000, .pd = 0x26, .d = 0x1c },
-       { .lomax = 305500, .pd = 0x25, .d = 0x1a },
-       { .lomax = 331000, .pd = 0x24, .d = 0x18 },
-       { .lomax = 361000, .pd = 0x23, .d = 0x16 },
-       { .lomax = 397500, .pd = 0x22, .d = 0x14 },
-       { .lomax = 441500, .pd = 0x21, .d = 0x12 },
-       { .lomax = 497000, .pd = 0x20, .d = 0x10 },
-       { .lomax = 530000, .pd = 0x17, .d = 0x0f },
-       { .lomax = 568000, .pd = 0x16, .d = 0x0e },
-       { .lomax = 611000, .pd = 0x15, .d = 0x0d },
-       { .lomax = 662000, .pd = 0x14, .d = 0x0c },
-       { .lomax = 722000, .pd = 0x13, .d = 0x0b },
-       { .lomax = 795000, .pd = 0x12, .d = 0x0a },
-       { .lomax = 883000, .pd = 0x11, .d = 0x09 },
-       { .lomax = 994000, .pd = 0x10, .d = 0x08 },
-       { .lomax =      0, .pd = 0x00, .d = 0x00 }, /* end */
-};
-
-static struct tda18271_pll_map tda18271c1_cal_pll[] = {
-       { .lomax =   33000, .pd = 0xdd, .d = 0xd0 },
-       { .lomax =   36000, .pd = 0xdc, .d = 0xc0 },
-       { .lomax =   40000, .pd = 0xdb, .d = 0xb0 },
-       { .lomax =   44000, .pd = 0xda, .d = 0xa0 },
-       { .lomax =   49000, .pd = 0xd9, .d = 0x90 },
-       { .lomax =   55000, .pd = 0xd8, .d = 0x80 },
-       { .lomax =   63000, .pd = 0xd3, .d = 0x70 },
-       { .lomax =   67000, .pd = 0xcd, .d = 0x68 },
-       { .lomax =   73000, .pd = 0xcc, .d = 0x60 },
-       { .lomax =   80000, .pd = 0xcb, .d = 0x58 },
-       { .lomax =   88000, .pd = 0xca, .d = 0x50 },
-       { .lomax =   98000, .pd = 0xc9, .d = 0x48 },
-       { .lomax =  110000, .pd = 0xc8, .d = 0x40 },
-       { .lomax =  126000, .pd = 0xc3, .d = 0x38 },
-       { .lomax =  135000, .pd = 0xbd, .d = 0x34 },
-       { .lomax =  147000, .pd = 0xbc, .d = 0x30 },
-       { .lomax =  160000, .pd = 0xbb, .d = 0x2c },
-       { .lomax =  176000, .pd = 0xba, .d = 0x28 },
-       { .lomax =  196000, .pd = 0xb9, .d = 0x24 },
-       { .lomax =  220000, .pd = 0xb8, .d = 0x20 },
-       { .lomax =  252000, .pd = 0xb3, .d = 0x1c },
-       { .lomax =  271000, .pd = 0xad, .d = 0x1a },
-       { .lomax =  294000, .pd = 0xac, .d = 0x18 },
-       { .lomax =  321000, .pd = 0xab, .d = 0x16 },
-       { .lomax =  353000, .pd = 0xaa, .d = 0x14 },
-       { .lomax =  392000, .pd = 0xa9, .d = 0x12 },
-       { .lomax =  441000, .pd = 0xa8, .d = 0x10 },
-       { .lomax =  505000, .pd = 0xa3, .d = 0x0e },
-       { .lomax =  543000, .pd = 0x9d, .d = 0x0d },
-       { .lomax =  589000, .pd = 0x9c, .d = 0x0c },
-       { .lomax =  642000, .pd = 0x9b, .d = 0x0b },
-       { .lomax =  707000, .pd = 0x9a, .d = 0x0a },
-       { .lomax =  785000, .pd = 0x99, .d = 0x09 },
-       { .lomax =  883000, .pd = 0x98, .d = 0x08 },
-       { .lomax = 1010000, .pd = 0x93, .d = 0x07 },
-       { .lomax =       0, .pd = 0x00, .d = 0x00 }, /* end */
-};
-
-static struct tda18271_pll_map tda18271c2_cal_pll[] = {
-       { .lomax =   33813, .pd = 0xdd, .d = 0xd0 },
-       { .lomax =   36625, .pd = 0xdc, .d = 0xc0 },
-       { .lomax =   39938, .pd = 0xdb, .d = 0xb0 },
-       { .lomax =   43938, .pd = 0xda, .d = 0xa0 },
-       { .lomax =   48813, .pd = 0xd9, .d = 0x90 },
-       { .lomax =   54938, .pd = 0xd8, .d = 0x80 },
-       { .lomax =   62813, .pd = 0xd3, .d = 0x70 },
-       { .lomax =   67625, .pd = 0xcd, .d = 0x68 },
-       { .lomax =   73250, .pd = 0xcc, .d = 0x60 },
-       { .lomax =   79875, .pd = 0xcb, .d = 0x58 },
-       { .lomax =   87875, .pd = 0xca, .d = 0x50 },
-       { .lomax =   97625, .pd = 0xc9, .d = 0x48 },
-       { .lomax =  109875, .pd = 0xc8, .d = 0x40 },
-       { .lomax =  125625, .pd = 0xc3, .d = 0x38 },
-       { .lomax =  135250, .pd = 0xbd, .d = 0x34 },
-       { .lomax =  146500, .pd = 0xbc, .d = 0x30 },
-       { .lomax =  159750, .pd = 0xbb, .d = 0x2c },
-       { .lomax =  175750, .pd = 0xba, .d = 0x28 },
-       { .lomax =  195250, .pd = 0xb9, .d = 0x24 },
-       { .lomax =  219750, .pd = 0xb8, .d = 0x20 },
-       { .lomax =  251250, .pd = 0xb3, .d = 0x1c },
-       { .lomax =  270500, .pd = 0xad, .d = 0x1a },
-       { .lomax =  293000, .pd = 0xac, .d = 0x18 },
-       { .lomax =  319500, .pd = 0xab, .d = 0x16 },
-       { .lomax =  351500, .pd = 0xaa, .d = 0x14 },
-       { .lomax =  390500, .pd = 0xa9, .d = 0x12 },
-       { .lomax =  439500, .pd = 0xa8, .d = 0x10 },
-       { .lomax =  502500, .pd = 0xa3, .d = 0x0e },
-       { .lomax =  541000, .pd = 0x9d, .d = 0x0d },
-       { .lomax =  586000, .pd = 0x9c, .d = 0x0c },
-       { .lomax =  639000, .pd = 0x9b, .d = 0x0b },
-       { .lomax =  703000, .pd = 0x9a, .d = 0x0a },
-       { .lomax =  781000, .pd = 0x99, .d = 0x09 },
-       { .lomax =  879000, .pd = 0x98, .d = 0x08 },
-       { .lomax =       0, .pd = 0x00, .d = 0x00 }, /* end */
-};
-
-static struct tda18271_map tda18271_bp_filter[] = {
-       { .rfmax =  62000, .val = 0x00 },
-       { .rfmax =  84000, .val = 0x01 },
-       { .rfmax = 100000, .val = 0x02 },
-       { .rfmax = 140000, .val = 0x03 },
-       { .rfmax = 170000, .val = 0x04 },
-       { .rfmax = 180000, .val = 0x05 },
-       { .rfmax = 865000, .val = 0x06 },
-       { .rfmax =      0, .val = 0x00 }, /* end */
-};
-
-static struct tda18271_map tda18271c1_km[] = {
-       { .rfmax =  61100, .val = 0x74 },
-       { .rfmax = 350000, .val = 0x40 },
-       { .rfmax = 720000, .val = 0x30 },
-       { .rfmax = 865000, .val = 0x40 },
-       { .rfmax =      0, .val = 0x00 }, /* end */
-};
-
-static struct tda18271_map tda18271c2_km[] = {
-       { .rfmax =  47900, .val = 0x38 },
-       { .rfmax =  61100, .val = 0x44 },
-       { .rfmax = 350000, .val = 0x30 },
-       { .rfmax = 720000, .val = 0x24 },
-       { .rfmax = 865000, .val = 0x3c },
-       { .rfmax =      0, .val = 0x00 }, /* end */
-};
-
-static struct tda18271_map tda18271_rf_band[] = {
-       { .rfmax =  47900, .val = 0x00 },
-       { .rfmax =  61100, .val = 0x01 },
-       { .rfmax = 152600, .val = 0x02 },
-       { .rfmax = 164700, .val = 0x03 },
-       { .rfmax = 203500, .val = 0x04 },
-       { .rfmax = 457800, .val = 0x05 },
-       { .rfmax = 865000, .val = 0x06 },
-       { .rfmax =      0, .val = 0x00 }, /* end */
-};
-
-static struct tda18271_map tda18271_gain_taper[] = {
-       { .rfmax =  45400, .val = 0x1f },
-       { .rfmax =  45800, .val = 0x1e },
-       { .rfmax =  46200, .val = 0x1d },
-       { .rfmax =  46700, .val = 0x1c },
-       { .rfmax =  47100, .val = 0x1b },
-       { .rfmax =  47500, .val = 0x1a },
-       { .rfmax =  47900, .val = 0x19 },
-       { .rfmax =  49600, .val = 0x17 },
-       { .rfmax =  51200, .val = 0x16 },
-       { .rfmax =  52900, .val = 0x15 },
-       { .rfmax =  54500, .val = 0x14 },
-       { .rfmax =  56200, .val = 0x13 },
-       { .rfmax =  57800, .val = 0x12 },
-       { .rfmax =  59500, .val = 0x11 },
-       { .rfmax =  61100, .val = 0x10 },
-       { .rfmax =  67600, .val = 0x0d },
-       { .rfmax =  74200, .val = 0x0c },
-       { .rfmax =  80700, .val = 0x0b },
-       { .rfmax =  87200, .val = 0x0a },
-       { .rfmax =  93800, .val = 0x09 },
-       { .rfmax = 100300, .val = 0x08 },
-       { .rfmax = 106900, .val = 0x07 },
-       { .rfmax = 113400, .val = 0x06 },
-       { .rfmax = 119900, .val = 0x05 },
-       { .rfmax = 126500, .val = 0x04 },
-       { .rfmax = 133000, .val = 0x03 },
-       { .rfmax = 139500, .val = 0x02 },
-       { .rfmax = 146100, .val = 0x01 },
-       { .rfmax = 152600, .val = 0x00 },
-       { .rfmax = 154300, .val = 0x1f },
-       { .rfmax = 156100, .val = 0x1e },
-       { .rfmax = 157800, .val = 0x1d },
-       { .rfmax = 159500, .val = 0x1c },
-       { .rfmax = 161200, .val = 0x1b },
-       { .rfmax = 163000, .val = 0x1a },
-       { .rfmax = 164700, .val = 0x19 },
-       { .rfmax = 170200, .val = 0x17 },
-       { .rfmax = 175800, .val = 0x16 },
-       { .rfmax = 181300, .val = 0x15 },
-       { .rfmax = 186900, .val = 0x14 },
-       { .rfmax = 192400, .val = 0x13 },
-       { .rfmax = 198000, .val = 0x12 },
-       { .rfmax = 203500, .val = 0x11 },
-       { .rfmax = 216200, .val = 0x14 },
-       { .rfmax = 228900, .val = 0x13 },
-       { .rfmax = 241600, .val = 0x12 },
-       { .rfmax = 254400, .val = 0x11 },
-       { .rfmax = 267100, .val = 0x10 },
-       { .rfmax = 279800, .val = 0x0f },
-       { .rfmax = 292500, .val = 0x0e },
-       { .rfmax = 305200, .val = 0x0d },
-       { .rfmax = 317900, .val = 0x0c },
-       { .rfmax = 330700, .val = 0x0b },
-       { .rfmax = 343400, .val = 0x0a },
-       { .rfmax = 356100, .val = 0x09 },
-       { .rfmax = 368800, .val = 0x08 },
-       { .rfmax = 381500, .val = 0x07 },
-       { .rfmax = 394200, .val = 0x06 },
-       { .rfmax = 406900, .val = 0x05 },
-       { .rfmax = 419700, .val = 0x04 },
-       { .rfmax = 432400, .val = 0x03 },
-       { .rfmax = 445100, .val = 0x02 },
-       { .rfmax = 457800, .val = 0x01 },
-       { .rfmax = 476300, .val = 0x19 },
-       { .rfmax = 494800, .val = 0x18 },
-       { .rfmax = 513300, .val = 0x17 },
-       { .rfmax = 531800, .val = 0x16 },
-       { .rfmax = 550300, .val = 0x15 },
-       { .rfmax = 568900, .val = 0x14 },
-       { .rfmax = 587400, .val = 0x13 },
-       { .rfmax = 605900, .val = 0x12 },
-       { .rfmax = 624400, .val = 0x11 },
-       { .rfmax = 642900, .val = 0x10 },
-       { .rfmax = 661400, .val = 0x0f },
-       { .rfmax = 679900, .val = 0x0e },
-       { .rfmax = 698400, .val = 0x0d },
-       { .rfmax = 716900, .val = 0x0c },
-       { .rfmax = 735400, .val = 0x0b },
-       { .rfmax = 753900, .val = 0x0a },
-       { .rfmax = 772500, .val = 0x09 },
-       { .rfmax = 791000, .val = 0x08 },
-       { .rfmax = 809500, .val = 0x07 },
-       { .rfmax = 828000, .val = 0x06 },
-       { .rfmax = 846500, .val = 0x05 },
-       { .rfmax = 865000, .val = 0x04 },
-       { .rfmax =      0, .val = 0x00 }, /* end */
-};
-
-static struct tda18271_map tda18271c1_rf_cal[] = {
-       { .rfmax = 41000, .val = 0x1e },
-       { .rfmax = 43000, .val = 0x30 },
-       { .rfmax = 45000, .val = 0x43 },
-       { .rfmax = 46000, .val = 0x4d },
-       { .rfmax = 47000, .val = 0x54 },
-       { .rfmax = 47900, .val = 0x64 },
-       { .rfmax = 49100, .val = 0x20 },
-       { .rfmax = 50000, .val = 0x22 },
-       { .rfmax = 51000, .val = 0x2a },
-       { .rfmax = 53000, .val = 0x32 },
-       { .rfmax = 55000, .val = 0x35 },
-       { .rfmax = 56000, .val = 0x3c },
-       { .rfmax = 57000, .val = 0x3f },
-       { .rfmax = 58000, .val = 0x48 },
-       { .rfmax = 59000, .val = 0x4d },
-       { .rfmax = 60000, .val = 0x58 },
-       { .rfmax = 61100, .val = 0x5f },
-       { .rfmax =     0, .val = 0x00 }, /* end */
-};
-
-static struct tda18271_map tda18271c2_rf_cal[] = {
-       { .rfmax =  41000, .val = 0x0f },
-       { .rfmax =  43000, .val = 0x1c },
-       { .rfmax =  45000, .val = 0x2f },
-       { .rfmax =  46000, .val = 0x39 },
-       { .rfmax =  47000, .val = 0x40 },
-       { .rfmax =  47900, .val = 0x50 },
-       { .rfmax =  49100, .val = 0x16 },
-       { .rfmax =  50000, .val = 0x18 },
-       { .rfmax =  51000, .val = 0x20 },
-       { .rfmax =  53000, .val = 0x28 },
-       { .rfmax =  55000, .val = 0x2b },
-       { .rfmax =  56000, .val = 0x32 },
-       { .rfmax =  57000, .val = 0x35 },
-       { .rfmax =  58000, .val = 0x3e },
-       { .rfmax =  59000, .val = 0x43 },
-       { .rfmax =  60000, .val = 0x4e },
-       { .rfmax =  61100, .val = 0x55 },
-       { .rfmax =  63000, .val = 0x0f },
-       { .rfmax =  64000, .val = 0x11 },
-       { .rfmax =  65000, .val = 0x12 },
-       { .rfmax =  66000, .val = 0x15 },
-       { .rfmax =  67000, .val = 0x16 },
-       { .rfmax =  68000, .val = 0x17 },
-       { .rfmax =  70000, .val = 0x19 },
-       { .rfmax =  71000, .val = 0x1c },
-       { .rfmax =  72000, .val = 0x1d },
-       { .rfmax =  73000, .val = 0x1f },
-       { .rfmax =  74000, .val = 0x20 },
-       { .rfmax =  75000, .val = 0x21 },
-       { .rfmax =  76000, .val = 0x24 },
-       { .rfmax =  77000, .val = 0x25 },
-       { .rfmax =  78000, .val = 0x27 },
-       { .rfmax =  80000, .val = 0x28 },
-       { .rfmax =  81000, .val = 0x29 },
-       { .rfmax =  82000, .val = 0x2d },
-       { .rfmax =  83000, .val = 0x2e },
-       { .rfmax =  84000, .val = 0x2f },
-       { .rfmax =  85000, .val = 0x31 },
-       { .rfmax =  86000, .val = 0x33 },
-       { .rfmax =  87000, .val = 0x34 },
-       { .rfmax =  88000, .val = 0x35 },
-       { .rfmax =  89000, .val = 0x37 },
-       { .rfmax =  90000, .val = 0x38 },
-       { .rfmax =  91000, .val = 0x39 },
-       { .rfmax =  93000, .val = 0x3c },
-       { .rfmax =  94000, .val = 0x3e },
-       { .rfmax =  95000, .val = 0x3f },
-       { .rfmax =  96000, .val = 0x40 },
-       { .rfmax =  97000, .val = 0x42 },
-       { .rfmax =  99000, .val = 0x45 },
-       { .rfmax = 100000, .val = 0x46 },
-       { .rfmax = 102000, .val = 0x48 },
-       { .rfmax = 103000, .val = 0x4a },
-       { .rfmax = 105000, .val = 0x4d },
-       { .rfmax = 106000, .val = 0x4e },
-       { .rfmax = 107000, .val = 0x50 },
-       { .rfmax = 108000, .val = 0x51 },
-       { .rfmax = 110000, .val = 0x54 },
-       { .rfmax = 111000, .val = 0x56 },
-       { .rfmax = 112000, .val = 0x57 },
-       { .rfmax = 113000, .val = 0x58 },
-       { .rfmax = 114000, .val = 0x59 },
-       { .rfmax = 115000, .val = 0x5c },
-       { .rfmax = 116000, .val = 0x5d },
-       { .rfmax = 117000, .val = 0x5f },
-       { .rfmax = 119000, .val = 0x60 },
-       { .rfmax = 120000, .val = 0x64 },
-       { .rfmax = 121000, .val = 0x65 },
-       { .rfmax = 122000, .val = 0x66 },
-       { .rfmax = 123000, .val = 0x68 },
-       { .rfmax = 124000, .val = 0x69 },
-       { .rfmax = 125000, .val = 0x6c },
-       { .rfmax = 126000, .val = 0x6d },
-       { .rfmax = 127000, .val = 0x6e },
-       { .rfmax = 128000, .val = 0x70 },
-       { .rfmax = 129000, .val = 0x71 },
-       { .rfmax = 130000, .val = 0x75 },
-       { .rfmax = 131000, .val = 0x77 },
-       { .rfmax = 132000, .val = 0x78 },
-       { .rfmax = 133000, .val = 0x7b },
-       { .rfmax = 134000, .val = 0x7e },
-       { .rfmax = 135000, .val = 0x81 },
-       { .rfmax = 136000, .val = 0x82 },
-       { .rfmax = 137000, .val = 0x87 },
-       { .rfmax = 138000, .val = 0x88 },
-       { .rfmax = 139000, .val = 0x8d },
-       { .rfmax = 140000, .val = 0x8e },
-       { .rfmax = 141000, .val = 0x91 },
-       { .rfmax = 142000, .val = 0x95 },
-       { .rfmax = 143000, .val = 0x9a },
-       { .rfmax = 144000, .val = 0x9d },
-       { .rfmax = 145000, .val = 0xa1 },
-       { .rfmax = 146000, .val = 0xa2 },
-       { .rfmax = 147000, .val = 0xa4 },
-       { .rfmax = 148000, .val = 0xa9 },
-       { .rfmax = 149000, .val = 0xae },
-       { .rfmax = 150000, .val = 0xb0 },
-       { .rfmax = 151000, .val = 0xb1 },
-       { .rfmax = 152000, .val = 0xb7 },
-       { .rfmax = 152600, .val = 0xbd },
-       { .rfmax = 154000, .val = 0x20 },
-       { .rfmax = 155000, .val = 0x22 },
-       { .rfmax = 156000, .val = 0x24 },
-       { .rfmax = 157000, .val = 0x25 },
-       { .rfmax = 158000, .val = 0x27 },
-       { .rfmax = 159000, .val = 0x29 },
-       { .rfmax = 160000, .val = 0x2c },
-       { .rfmax = 161000, .val = 0x2d },
-       { .rfmax = 163000, .val = 0x2e },
-       { .rfmax = 164000, .val = 0x2f },
-       { .rfmax = 164700, .val = 0x30 },
-       { .rfmax = 166000, .val = 0x11 },
-       { .rfmax = 167000, .val = 0x12 },
-       { .rfmax = 168000, .val = 0x13 },
-       { .rfmax = 169000, .val = 0x14 },
-       { .rfmax = 170000, .val = 0x15 },
-       { .rfmax = 172000, .val = 0x16 },
-       { .rfmax = 173000, .val = 0x17 },
-       { .rfmax = 174000, .val = 0x18 },
-       { .rfmax = 175000, .val = 0x1a },
-       { .rfmax = 176000, .val = 0x1b },
-       { .rfmax = 178000, .val = 0x1d },
-       { .rfmax = 179000, .val = 0x1e },
-       { .rfmax = 180000, .val = 0x1f },
-       { .rfmax = 181000, .val = 0x20 },
-       { .rfmax = 182000, .val = 0x21 },
-       { .rfmax = 183000, .val = 0x22 },
-       { .rfmax = 184000, .val = 0x24 },
-       { .rfmax = 185000, .val = 0x25 },
-       { .rfmax = 186000, .val = 0x26 },
-       { .rfmax = 187000, .val = 0x27 },
-       { .rfmax = 188000, .val = 0x29 },
-       { .rfmax = 189000, .val = 0x2a },
-       { .rfmax = 190000, .val = 0x2c },
-       { .rfmax = 191000, .val = 0x2d },
-       { .rfmax = 192000, .val = 0x2e },
-       { .rfmax = 193000, .val = 0x2f },
-       { .rfmax = 194000, .val = 0x30 },
-       { .rfmax = 195000, .val = 0x33 },
-       { .rfmax = 196000, .val = 0x35 },
-       { .rfmax = 198000, .val = 0x36 },
-       { .rfmax = 200000, .val = 0x38 },
-       { .rfmax = 201000, .val = 0x3c },
-       { .rfmax = 202000, .val = 0x3d },
-       { .rfmax = 203500, .val = 0x3e },
-       { .rfmax = 206000, .val = 0x0e },
-       { .rfmax = 208000, .val = 0x0f },
-       { .rfmax = 212000, .val = 0x10 },
-       { .rfmax = 216000, .val = 0x11 },
-       { .rfmax = 217000, .val = 0x12 },
-       { .rfmax = 218000, .val = 0x13 },
-       { .rfmax = 220000, .val = 0x14 },
-       { .rfmax = 222000, .val = 0x15 },
-       { .rfmax = 225000, .val = 0x16 },
-       { .rfmax = 228000, .val = 0x17 },
-       { .rfmax = 231000, .val = 0x18 },
-       { .rfmax = 234000, .val = 0x19 },
-       { .rfmax = 235000, .val = 0x1a },
-       { .rfmax = 236000, .val = 0x1b },
-       { .rfmax = 237000, .val = 0x1c },
-       { .rfmax = 240000, .val = 0x1d },
-       { .rfmax = 242000, .val = 0x1e },
-       { .rfmax = 244000, .val = 0x1f },
-       { .rfmax = 247000, .val = 0x20 },
-       { .rfmax = 249000, .val = 0x21 },
-       { .rfmax = 252000, .val = 0x22 },
-       { .rfmax = 253000, .val = 0x23 },
-       { .rfmax = 254000, .val = 0x24 },
-       { .rfmax = 256000, .val = 0x25 },
-       { .rfmax = 259000, .val = 0x26 },
-       { .rfmax = 262000, .val = 0x27 },
-       { .rfmax = 264000, .val = 0x28 },
-       { .rfmax = 267000, .val = 0x29 },
-       { .rfmax = 269000, .val = 0x2a },
-       { .rfmax = 271000, .val = 0x2b },
-       { .rfmax = 273000, .val = 0x2c },
-       { .rfmax = 275000, .val = 0x2d },
-       { .rfmax = 277000, .val = 0x2e },
-       { .rfmax = 279000, .val = 0x2f },
-       { .rfmax = 282000, .val = 0x30 },
-       { .rfmax = 284000, .val = 0x31 },
-       { .rfmax = 286000, .val = 0x32 },
-       { .rfmax = 287000, .val = 0x33 },
-       { .rfmax = 290000, .val = 0x34 },
-       { .rfmax = 293000, .val = 0x35 },
-       { .rfmax = 295000, .val = 0x36 },
-       { .rfmax = 297000, .val = 0x37 },
-       { .rfmax = 300000, .val = 0x38 },
-       { .rfmax = 303000, .val = 0x39 },
-       { .rfmax = 305000, .val = 0x3a },
-       { .rfmax = 306000, .val = 0x3b },
-       { .rfmax = 307000, .val = 0x3c },
-       { .rfmax = 310000, .val = 0x3d },
-       { .rfmax = 312000, .val = 0x3e },
-       { .rfmax = 315000, .val = 0x3f },
-       { .rfmax = 318000, .val = 0x40 },
-       { .rfmax = 320000, .val = 0x41 },
-       { .rfmax = 323000, .val = 0x42 },
-       { .rfmax = 324000, .val = 0x43 },
-       { .rfmax = 325000, .val = 0x44 },
-       { .rfmax = 327000, .val = 0x45 },
-       { .rfmax = 331000, .val = 0x46 },
-       { .rfmax = 334000, .val = 0x47 },
-       { .rfmax = 337000, .val = 0x48 },
-       { .rfmax = 339000, .val = 0x49 },
-       { .rfmax = 340000, .val = 0x4a },
-       { .rfmax = 341000, .val = 0x4b },
-       { .rfmax = 343000, .val = 0x4c },
-       { .rfmax = 345000, .val = 0x4d },
-       { .rfmax = 349000, .val = 0x4e },
-       { .rfmax = 352000, .val = 0x4f },
-       { .rfmax = 353000, .val = 0x50 },
-       { .rfmax = 355000, .val = 0x51 },
-       { .rfmax = 357000, .val = 0x52 },
-       { .rfmax = 359000, .val = 0x53 },
-       { .rfmax = 361000, .val = 0x54 },
-       { .rfmax = 362000, .val = 0x55 },
-       { .rfmax = 364000, .val = 0x56 },
-       { .rfmax = 368000, .val = 0x57 },
-       { .rfmax = 370000, .val = 0x58 },
-       { .rfmax = 372000, .val = 0x59 },
-       { .rfmax = 375000, .val = 0x5a },
-       { .rfmax = 376000, .val = 0x5b },
-       { .rfmax = 377000, .val = 0x5c },
-       { .rfmax = 379000, .val = 0x5d },
-       { .rfmax = 382000, .val = 0x5e },
-       { .rfmax = 384000, .val = 0x5f },
-       { .rfmax = 385000, .val = 0x60 },
-       { .rfmax = 386000, .val = 0x61 },
-       { .rfmax = 388000, .val = 0x62 },
-       { .rfmax = 390000, .val = 0x63 },
-       { .rfmax = 393000, .val = 0x64 },
-       { .rfmax = 394000, .val = 0x65 },
-       { .rfmax = 396000, .val = 0x66 },
-       { .rfmax = 397000, .val = 0x67 },
-       { .rfmax = 398000, .val = 0x68 },
-       { .rfmax = 400000, .val = 0x69 },
-       { .rfmax = 402000, .val = 0x6a },
-       { .rfmax = 403000, .val = 0x6b },
-       { .rfmax = 407000, .val = 0x6c },
-       { .rfmax = 408000, .val = 0x6d },
-       { .rfmax = 409000, .val = 0x6e },
-       { .rfmax = 410000, .val = 0x6f },
-       { .rfmax = 411000, .val = 0x70 },
-       { .rfmax = 412000, .val = 0x71 },
-       { .rfmax = 413000, .val = 0x72 },
-       { .rfmax = 414000, .val = 0x73 },
-       { .rfmax = 417000, .val = 0x74 },
-       { .rfmax = 418000, .val = 0x75 },
-       { .rfmax = 420000, .val = 0x76 },
-       { .rfmax = 422000, .val = 0x77 },
-       { .rfmax = 423000, .val = 0x78 },
-       { .rfmax = 424000, .val = 0x79 },
-       { .rfmax = 427000, .val = 0x7a },
-       { .rfmax = 428000, .val = 0x7b },
-       { .rfmax = 429000, .val = 0x7d },
-       { .rfmax = 432000, .val = 0x7f },
-       { .rfmax = 434000, .val = 0x80 },
-       { .rfmax = 435000, .val = 0x81 },
-       { .rfmax = 436000, .val = 0x83 },
-       { .rfmax = 437000, .val = 0x84 },
-       { .rfmax = 438000, .val = 0x85 },
-       { .rfmax = 439000, .val = 0x86 },
-       { .rfmax = 440000, .val = 0x87 },
-       { .rfmax = 441000, .val = 0x88 },
-       { .rfmax = 442000, .val = 0x89 },
-       { .rfmax = 445000, .val = 0x8a },
-       { .rfmax = 446000, .val = 0x8b },
-       { .rfmax = 447000, .val = 0x8c },
-       { .rfmax = 448000, .val = 0x8e },
-       { .rfmax = 449000, .val = 0x8f },
-       { .rfmax = 450000, .val = 0x90 },
-       { .rfmax = 452000, .val = 0x91 },
-       { .rfmax = 453000, .val = 0x93 },
-       { .rfmax = 454000, .val = 0x94 },
-       { .rfmax = 456000, .val = 0x96 },
-       { .rfmax = 457800, .val = 0x98 },
-       { .rfmax = 461000, .val = 0x11 },
-       { .rfmax = 468000, .val = 0x12 },
-       { .rfmax = 472000, .val = 0x13 },
-       { .rfmax = 473000, .val = 0x14 },
-       { .rfmax = 474000, .val = 0x15 },
-       { .rfmax = 481000, .val = 0x16 },
-       { .rfmax = 486000, .val = 0x17 },
-       { .rfmax = 491000, .val = 0x18 },
-       { .rfmax = 498000, .val = 0x19 },
-       { .rfmax = 499000, .val = 0x1a },
-       { .rfmax = 501000, .val = 0x1b },
-       { .rfmax = 506000, .val = 0x1c },
-       { .rfmax = 511000, .val = 0x1d },
-       { .rfmax = 516000, .val = 0x1e },
-       { .rfmax = 520000, .val = 0x1f },
-       { .rfmax = 521000, .val = 0x20 },
-       { .rfmax = 525000, .val = 0x21 },
-       { .rfmax = 529000, .val = 0x22 },
-       { .rfmax = 533000, .val = 0x23 },
-       { .rfmax = 539000, .val = 0x24 },
-       { .rfmax = 541000, .val = 0x25 },
-       { .rfmax = 547000, .val = 0x26 },
-       { .rfmax = 549000, .val = 0x27 },
-       { .rfmax = 551000, .val = 0x28 },
-       { .rfmax = 556000, .val = 0x29 },
-       { .rfmax = 561000, .val = 0x2a },
-       { .rfmax = 563000, .val = 0x2b },
-       { .rfmax = 565000, .val = 0x2c },
-       { .rfmax = 569000, .val = 0x2d },
-       { .rfmax = 571000, .val = 0x2e },
-       { .rfmax = 577000, .val = 0x2f },
-       { .rfmax = 580000, .val = 0x30 },
-       { .rfmax = 582000, .val = 0x31 },
-       { .rfmax = 584000, .val = 0x32 },
-       { .rfmax = 588000, .val = 0x33 },
-       { .rfmax = 591000, .val = 0x34 },
-       { .rfmax = 596000, .val = 0x35 },
-       { .rfmax = 598000, .val = 0x36 },
-       { .rfmax = 603000, .val = 0x37 },
-       { .rfmax = 604000, .val = 0x38 },
-       { .rfmax = 606000, .val = 0x39 },
-       { .rfmax = 612000, .val = 0x3a },
-       { .rfmax = 615000, .val = 0x3b },
-       { .rfmax = 617000, .val = 0x3c },
-       { .rfmax = 621000, .val = 0x3d },
-       { .rfmax = 622000, .val = 0x3e },
-       { .rfmax = 625000, .val = 0x3f },
-       { .rfmax = 632000, .val = 0x40 },
-       { .rfmax = 633000, .val = 0x41 },
-       { .rfmax = 634000, .val = 0x42 },
-       { .rfmax = 642000, .val = 0x43 },
-       { .rfmax = 643000, .val = 0x44 },
-       { .rfmax = 647000, .val = 0x45 },
-       { .rfmax = 650000, .val = 0x46 },
-       { .rfmax = 652000, .val = 0x47 },
-       { .rfmax = 657000, .val = 0x48 },
-       { .rfmax = 661000, .val = 0x49 },
-       { .rfmax = 662000, .val = 0x4a },
-       { .rfmax = 665000, .val = 0x4b },
-       { .rfmax = 667000, .val = 0x4c },
-       { .rfmax = 670000, .val = 0x4d },
-       { .rfmax = 673000, .val = 0x4e },
-       { .rfmax = 676000, .val = 0x4f },
-       { .rfmax = 677000, .val = 0x50 },
-       { .rfmax = 681000, .val = 0x51 },
-       { .rfmax = 683000, .val = 0x52 },
-       { .rfmax = 686000, .val = 0x53 },
-       { .rfmax = 688000, .val = 0x54 },
-       { .rfmax = 689000, .val = 0x55 },
-       { .rfmax = 691000, .val = 0x56 },
-       { .rfmax = 695000, .val = 0x57 },
-       { .rfmax = 698000, .val = 0x58 },
-       { .rfmax = 703000, .val = 0x59 },
-       { .rfmax = 704000, .val = 0x5a },
-       { .rfmax = 705000, .val = 0x5b },
-       { .rfmax = 707000, .val = 0x5c },
-       { .rfmax = 710000, .val = 0x5d },
-       { .rfmax = 712000, .val = 0x5e },
-       { .rfmax = 717000, .val = 0x5f },
-       { .rfmax = 718000, .val = 0x60 },
-       { .rfmax = 721000, .val = 0x61 },
-       { .rfmax = 722000, .val = 0x62 },
-       { .rfmax = 723000, .val = 0x63 },
-       { .rfmax = 725000, .val = 0x64 },
-       { .rfmax = 727000, .val = 0x65 },
-       { .rfmax = 730000, .val = 0x66 },
-       { .rfmax = 732000, .val = 0x67 },
-       { .rfmax = 735000, .val = 0x68 },
-       { .rfmax = 740000, .val = 0x69 },
-       { .rfmax = 741000, .val = 0x6a },
-       { .rfmax = 742000, .val = 0x6b },
-       { .rfmax = 743000, .val = 0x6c },
-       { .rfmax = 745000, .val = 0x6d },
-       { .rfmax = 747000, .val = 0x6e },
-       { .rfmax = 748000, .val = 0x6f },
-       { .rfmax = 750000, .val = 0x70 },
-       { .rfmax = 752000, .val = 0x71 },
-       { .rfmax = 754000, .val = 0x72 },
-       { .rfmax = 757000, .val = 0x73 },
-       { .rfmax = 758000, .val = 0x74 },
-       { .rfmax = 760000, .val = 0x75 },
-       { .rfmax = 763000, .val = 0x76 },
-       { .rfmax = 764000, .val = 0x77 },
-       { .rfmax = 766000, .val = 0x78 },
-       { .rfmax = 767000, .val = 0x79 },
-       { .rfmax = 768000, .val = 0x7a },
-       { .rfmax = 773000, .val = 0x7b },
-       { .rfmax = 774000, .val = 0x7c },
-       { .rfmax = 776000, .val = 0x7d },
-       { .rfmax = 777000, .val = 0x7e },
-       { .rfmax = 778000, .val = 0x7f },
-       { .rfmax = 779000, .val = 0x80 },
-       { .rfmax = 781000, .val = 0x81 },
-       { .rfmax = 783000, .val = 0x82 },
-       { .rfmax = 784000, .val = 0x83 },
-       { .rfmax = 785000, .val = 0x84 },
-       { .rfmax = 786000, .val = 0x85 },
-       { .rfmax = 793000, .val = 0x86 },
-       { .rfmax = 794000, .val = 0x87 },
-       { .rfmax = 795000, .val = 0x88 },
-       { .rfmax = 797000, .val = 0x89 },
-       { .rfmax = 799000, .val = 0x8a },
-       { .rfmax = 801000, .val = 0x8b },
-       { .rfmax = 802000, .val = 0x8c },
-       { .rfmax = 803000, .val = 0x8d },
-       { .rfmax = 804000, .val = 0x8e },
-       { .rfmax = 810000, .val = 0x90 },
-       { .rfmax = 811000, .val = 0x91 },
-       { .rfmax = 812000, .val = 0x92 },
-       { .rfmax = 814000, .val = 0x93 },
-       { .rfmax = 816000, .val = 0x94 },
-       { .rfmax = 817000, .val = 0x96 },
-       { .rfmax = 818000, .val = 0x97 },
-       { .rfmax = 820000, .val = 0x98 },
-       { .rfmax = 821000, .val = 0x99 },
-       { .rfmax = 822000, .val = 0x9a },
-       { .rfmax = 828000, .val = 0x9b },
-       { .rfmax = 829000, .val = 0x9d },
-       { .rfmax = 830000, .val = 0x9f },
-       { .rfmax = 831000, .val = 0xa0 },
-       { .rfmax = 833000, .val = 0xa1 },
-       { .rfmax = 835000, .val = 0xa2 },
-       { .rfmax = 836000, .val = 0xa3 },
-       { .rfmax = 837000, .val = 0xa4 },
-       { .rfmax = 838000, .val = 0xa6 },
-       { .rfmax = 840000, .val = 0xa8 },
-       { .rfmax = 842000, .val = 0xa9 },
-       { .rfmax = 845000, .val = 0xaa },
-       { .rfmax = 846000, .val = 0xab },
-       { .rfmax = 847000, .val = 0xad },
-       { .rfmax = 848000, .val = 0xae },
-       { .rfmax = 852000, .val = 0xaf },
-       { .rfmax = 853000, .val = 0xb0 },
-       { .rfmax = 858000, .val = 0xb1 },
-       { .rfmax = 860000, .val = 0xb2 },
-       { .rfmax = 861000, .val = 0xb3 },
-       { .rfmax = 862000, .val = 0xb4 },
-       { .rfmax = 863000, .val = 0xb6 },
-       { .rfmax = 864000, .val = 0xb8 },
-       { .rfmax = 865000, .val = 0xb9 },
-       { .rfmax =      0, .val = 0x00 }, /* end */
-};
-
-static struct tda18271_map tda18271_ir_measure[] = {
-       { .rfmax =  30000, .val = 4 },
-       { .rfmax = 200000, .val = 5 },
-       { .rfmax = 600000, .val = 6 },
-       { .rfmax = 865000, .val = 7 },
-       { .rfmax =      0, .val = 0 }, /* end */
-};
-
-static struct tda18271_map tda18271_rf_cal_dc_over_dt[] = {
-       { .rfmax =  47900, .val = 0x00 },
-       { .rfmax =  55000, .val = 0x00 },
-       { .rfmax =  61100, .val = 0x0a },
-       { .rfmax =  64000, .val = 0x0a },
-       { .rfmax =  82000, .val = 0x14 },
-       { .rfmax =  84000, .val = 0x19 },
-       { .rfmax = 119000, .val = 0x1c },
-       { .rfmax = 124000, .val = 0x20 },
-       { .rfmax = 129000, .val = 0x2a },
-       { .rfmax = 134000, .val = 0x32 },
-       { .rfmax = 139000, .val = 0x39 },
-       { .rfmax = 144000, .val = 0x3e },
-       { .rfmax = 149000, .val = 0x3f },
-       { .rfmax = 152600, .val = 0x40 },
-       { .rfmax = 154000, .val = 0x40 },
-       { .rfmax = 164700, .val = 0x41 },
-       { .rfmax = 203500, .val = 0x32 },
-       { .rfmax = 353000, .val = 0x19 },
-       { .rfmax = 356000, .val = 0x1a },
-       { .rfmax = 359000, .val = 0x1b },
-       { .rfmax = 363000, .val = 0x1c },
-       { .rfmax = 366000, .val = 0x1d },
-       { .rfmax = 369000, .val = 0x1e },
-       { .rfmax = 373000, .val = 0x1f },
-       { .rfmax = 376000, .val = 0x20 },
-       { .rfmax = 379000, .val = 0x21 },
-       { .rfmax = 383000, .val = 0x22 },
-       { .rfmax = 386000, .val = 0x23 },
-       { .rfmax = 389000, .val = 0x24 },
-       { .rfmax = 393000, .val = 0x25 },
-       { .rfmax = 396000, .val = 0x26 },
-       { .rfmax = 399000, .val = 0x27 },
-       { .rfmax = 402000, .val = 0x28 },
-       { .rfmax = 404000, .val = 0x29 },
-       { .rfmax = 407000, .val = 0x2a },
-       { .rfmax = 409000, .val = 0x2b },
-       { .rfmax = 412000, .val = 0x2c },
-       { .rfmax = 414000, .val = 0x2d },
-       { .rfmax = 417000, .val = 0x2e },
-       { .rfmax = 419000, .val = 0x2f },
-       { .rfmax = 422000, .val = 0x30 },
-       { .rfmax = 424000, .val = 0x31 },
-       { .rfmax = 427000, .val = 0x32 },
-       { .rfmax = 429000, .val = 0x33 },
-       { .rfmax = 432000, .val = 0x34 },
-       { .rfmax = 434000, .val = 0x35 },
-       { .rfmax = 437000, .val = 0x36 },
-       { .rfmax = 439000, .val = 0x37 },
-       { .rfmax = 442000, .val = 0x38 },
-       { .rfmax = 444000, .val = 0x39 },
-       { .rfmax = 447000, .val = 0x3a },
-       { .rfmax = 449000, .val = 0x3b },
-       { .rfmax = 457800, .val = 0x3c },
-       { .rfmax = 465000, .val = 0x0f },
-       { .rfmax = 477000, .val = 0x12 },
-       { .rfmax = 483000, .val = 0x14 },
-       { .rfmax = 502000, .val = 0x19 },
-       { .rfmax = 508000, .val = 0x1b },
-       { .rfmax = 519000, .val = 0x1c },
-       { .rfmax = 522000, .val = 0x1d },
-       { .rfmax = 524000, .val = 0x1e },
-       { .rfmax = 534000, .val = 0x1f },
-       { .rfmax = 549000, .val = 0x20 },
-       { .rfmax = 554000, .val = 0x22 },
-       { .rfmax = 584000, .val = 0x24 },
-       { .rfmax = 589000, .val = 0x26 },
-       { .rfmax = 658000, .val = 0x27 },
-       { .rfmax = 664000, .val = 0x2c },
-       { .rfmax = 669000, .val = 0x2d },
-       { .rfmax = 699000, .val = 0x2e },
-       { .rfmax = 704000, .val = 0x30 },
-       { .rfmax = 709000, .val = 0x31 },
-       { .rfmax = 714000, .val = 0x32 },
-       { .rfmax = 724000, .val = 0x33 },
-       { .rfmax = 729000, .val = 0x36 },
-       { .rfmax = 739000, .val = 0x38 },
-       { .rfmax = 744000, .val = 0x39 },
-       { .rfmax = 749000, .val = 0x3b },
-       { .rfmax = 754000, .val = 0x3c },
-       { .rfmax = 759000, .val = 0x3d },
-       { .rfmax = 764000, .val = 0x3e },
-       { .rfmax = 769000, .val = 0x3f },
-       { .rfmax = 774000, .val = 0x40 },
-       { .rfmax = 779000, .val = 0x41 },
-       { .rfmax = 784000, .val = 0x43 },
-       { .rfmax = 789000, .val = 0x46 },
-       { .rfmax = 794000, .val = 0x48 },
-       { .rfmax = 799000, .val = 0x4b },
-       { .rfmax = 804000, .val = 0x4f },
-       { .rfmax = 809000, .val = 0x54 },
-       { .rfmax = 814000, .val = 0x59 },
-       { .rfmax = 819000, .val = 0x5d },
-       { .rfmax = 824000, .val = 0x61 },
-       { .rfmax = 829000, .val = 0x68 },
-       { .rfmax = 834000, .val = 0x6e },
-       { .rfmax = 839000, .val = 0x75 },
-       { .rfmax = 844000, .val = 0x7e },
-       { .rfmax = 849000, .val = 0x82 },
-       { .rfmax = 854000, .val = 0x84 },
-       { .rfmax = 859000, .val = 0x8f },
-       { .rfmax = 865000, .val = 0x9a },
-       { .rfmax =      0, .val = 0x00 }, /* end */
-};
-
-/*---------------------------------------------------------------------*/
-
-struct tda18271_thermo_map {
-       u8 d;
-       u8 r0;
-       u8 r1;
-};
-
-static struct tda18271_thermo_map tda18271_thermometer[] = {
-       { .d = 0x00, .r0 = 60, .r1 =  92 },
-       { .d = 0x01, .r0 = 62, .r1 =  94 },
-       { .d = 0x02, .r0 = 66, .r1 =  98 },
-       { .d = 0x03, .r0 = 64, .r1 =  96 },
-       { .d = 0x04, .r0 = 74, .r1 = 106 },
-       { .d = 0x05, .r0 = 72, .r1 = 104 },
-       { .d = 0x06, .r0 = 68, .r1 = 100 },
-       { .d = 0x07, .r0 = 70, .r1 = 102 },
-       { .d = 0x08, .r0 = 90, .r1 = 122 },
-       { .d = 0x09, .r0 = 88, .r1 = 120 },
-       { .d = 0x0a, .r0 = 84, .r1 = 116 },
-       { .d = 0x0b, .r0 = 86, .r1 = 118 },
-       { .d = 0x0c, .r0 = 76, .r1 = 108 },
-       { .d = 0x0d, .r0 = 78, .r1 = 110 },
-       { .d = 0x0e, .r0 = 82, .r1 = 114 },
-       { .d = 0x0f, .r0 = 80, .r1 = 112 },
-       { .d = 0x00, .r0 =  0, .r1 =   0 }, /* end */
-};
-
-int tda18271_lookup_thermometer(struct dvb_frontend *fe)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       unsigned char *regs = priv->tda18271_regs;
-       int val, i = 0;
-
-       while (tda18271_thermometer[i].d < (regs[R_TM] & 0x0f)) {
-               if (tda18271_thermometer[i + 1].d == 0)
-                       break;
-               i++;
-       }
-
-       if ((regs[R_TM] & 0x20) == 0x20)
-               val = tda18271_thermometer[i].r1;
-       else
-               val = tda18271_thermometer[i].r0;
-
-       tda_map("(%d) tm = %d\n", i, val);
-
-       return val;
-}
-
-/*---------------------------------------------------------------------*/
-
-struct tda18271_cid_target_map {
-       u32 rfmax;
-       u8  target;
-       u16 limit;
-};
-
-static struct tda18271_cid_target_map tda18271_cid_target[] = {
-       { .rfmax =  46000, .target = 0x04, .limit =  1800 },
-       { .rfmax =  52200, .target = 0x0a, .limit =  1500 },
-       { .rfmax =  70100, .target = 0x01, .limit =  4000 },
-       { .rfmax = 136800, .target = 0x18, .limit =  4000 },
-       { .rfmax = 156700, .target = 0x18, .limit =  4000 },
-       { .rfmax = 186250, .target = 0x0a, .limit =  4000 },
-       { .rfmax = 230000, .target = 0x0a, .limit =  4000 },
-       { .rfmax = 345000, .target = 0x18, .limit =  4000 },
-       { .rfmax = 426000, .target = 0x0e, .limit =  4000 },
-       { .rfmax = 489500, .target = 0x1e, .limit =  4000 },
-       { .rfmax = 697500, .target = 0x32, .limit =  4000 },
-       { .rfmax = 842000, .target = 0x3a, .limit =  4000 },
-       { .rfmax =      0, .target = 0x00, .limit =     0 }, /* end */
-};
-
-int tda18271_lookup_cid_target(struct dvb_frontend *fe,
-                              u32 *freq, u8 *cid_target, u16 *count_limit)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       int i = 0;
-
-       while ((tda18271_cid_target[i].rfmax * 1000) < *freq) {
-               if (tda18271_cid_target[i + 1].rfmax == 0)
-                       break;
-               i++;
-       }
-       *cid_target  = tda18271_cid_target[i].target;
-       *count_limit = tda18271_cid_target[i].limit;
-
-       tda_map("(%d) cid_target = %02x, count_limit = %d\n", i,
-               tda18271_cid_target[i].target, tda18271_cid_target[i].limit);
-
-       return 0;
-}
-
-/*---------------------------------------------------------------------*/
-
-static struct tda18271_rf_tracking_filter_cal tda18271_rf_band_template[] = {
-       { .rfmax =  47900, .rfband = 0x00,
-         .rf1_def =  46000, .rf2_def =      0, .rf3_def =      0 },
-       { .rfmax =  61100, .rfband = 0x01,
-         .rf1_def =  52200, .rf2_def =      0, .rf3_def =      0 },
-       { .rfmax = 152600, .rfband = 0x02,
-         .rf1_def =  70100, .rf2_def = 136800, .rf3_def =      0 },
-       { .rfmax = 164700, .rfband = 0x03,
-         .rf1_def = 156700, .rf2_def =      0, .rf3_def =      0 },
-       { .rfmax = 203500, .rfband = 0x04,
-         .rf1_def = 186250, .rf2_def =      0, .rf3_def =      0 },
-       { .rfmax = 457800, .rfband = 0x05,
-         .rf1_def = 230000, .rf2_def = 345000, .rf3_def = 426000 },
-       { .rfmax = 865000, .rfband = 0x06,
-         .rf1_def = 489500, .rf2_def = 697500, .rf3_def = 842000 },
-       { .rfmax =      0, .rfband = 0x00,
-         .rf1_def =      0, .rf2_def =      0, .rf3_def =      0 }, /* end */
-};
-
-int tda18271_lookup_rf_band(struct dvb_frontend *fe, u32 *freq, u8 *rf_band)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
-       int i = 0;
-
-       while ((map[i].rfmax * 1000) < *freq) {
-               if (tda18271_debug & DBG_ADV)
-                       tda_map("(%d) rfmax = %d < freq = %d, "
-                               "rf1_def = %d, rf2_def = %d, rf3_def = %d, "
-                               "rf1 = %d, rf2 = %d, rf3 = %d, "
-                               "rf_a1 = %d, rf_a2 = %d, "
-                               "rf_b1 = %d, rf_b2 = %d\n",
-                               i, map[i].rfmax * 1000, *freq,
-                               map[i].rf1_def, map[i].rf2_def, map[i].rf3_def,
-                               map[i].rf1, map[i].rf2, map[i].rf3,
-                               map[i].rf_a1, map[i].rf_a2,
-                               map[i].rf_b1, map[i].rf_b2);
-               if (map[i].rfmax == 0)
-                       return -EINVAL;
-               i++;
-       }
-       if (rf_band)
-               *rf_band = map[i].rfband;
-
-       tda_map("(%d) rf_band = %02x\n", i, map[i].rfband);
-
-       return i;
-}
-
-/*---------------------------------------------------------------------*/
-
-struct tda18271_map_layout {
-       struct tda18271_pll_map *main_pll;
-       struct tda18271_pll_map *cal_pll;
-
-       struct tda18271_map *rf_cal;
-       struct tda18271_map *rf_cal_kmco;
-       struct tda18271_map *rf_cal_dc_over_dt;
-
-       struct tda18271_map *bp_filter;
-       struct tda18271_map *rf_band;
-       struct tda18271_map *gain_taper;
-       struct tda18271_map *ir_measure;
-};
-
-/*---------------------------------------------------------------------*/
-
-int tda18271_lookup_pll_map(struct dvb_frontend *fe,
-                           enum tda18271_map_type map_type,
-                           u32 *freq, u8 *post_div, u8 *div)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       struct tda18271_pll_map *map = NULL;
-       unsigned int i = 0;
-       char *map_name;
-       int ret = 0;
-
-       BUG_ON(!priv->maps);
-
-       switch (map_type) {
-       case MAIN_PLL:
-               map = priv->maps->main_pll;
-               map_name = "main_pll";
-               break;
-       case CAL_PLL:
-               map = priv->maps->cal_pll;
-               map_name = "cal_pll";
-               break;
-       default:
-               /* we should never get here */
-               map_name = "undefined";
-               break;
-       }
-
-       if (!map) {
-               tda_warn("%s map is not set!\n", map_name);
-               ret = -EINVAL;
-               goto fail;
-       }
-
-       while ((map[i].lomax * 1000) < *freq) {
-               if (map[i + 1].lomax == 0) {
-                       tda_map("%s: frequency (%d) out of range\n",
-                               map_name, *freq);
-                       ret = -ERANGE;
-                       break;
-               }
-               i++;
-       }
-       *post_div = map[i].pd;
-       *div      = map[i].d;
-
-       tda_map("(%d) %s: post div = 0x%02x, div = 0x%02x\n",
-               i, map_name, *post_div, *div);
-fail:
-       return ret;
-}
-
-int tda18271_lookup_map(struct dvb_frontend *fe,
-                       enum tda18271_map_type map_type,
-                       u32 *freq, u8 *val)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       struct tda18271_map *map = NULL;
-       unsigned int i = 0;
-       char *map_name;
-       int ret = 0;
-
-       BUG_ON(!priv->maps);
-
-       switch (map_type) {
-       case BP_FILTER:
-               map = priv->maps->bp_filter;
-               map_name = "bp_filter";
-               break;
-       case RF_CAL_KMCO:
-               map = priv->maps->rf_cal_kmco;
-               map_name = "km";
-               break;
-       case RF_BAND:
-               map = priv->maps->rf_band;
-               map_name = "rf_band";
-               break;
-       case GAIN_TAPER:
-               map = priv->maps->gain_taper;
-               map_name = "gain_taper";
-               break;
-       case RF_CAL:
-               map = priv->maps->rf_cal;
-               map_name = "rf_cal";
-               break;
-       case IR_MEASURE:
-               map = priv->maps->ir_measure;
-               map_name = "ir_measure";
-               break;
-       case RF_CAL_DC_OVER_DT:
-               map = priv->maps->rf_cal_dc_over_dt;
-               map_name = "rf_cal_dc_over_dt";
-               break;
-       default:
-               /* we should never get here */
-               map_name = "undefined";
-               break;
-       }
-
-       if (!map) {
-               tda_warn("%s map is not set!\n", map_name);
-               ret = -EINVAL;
-               goto fail;
-       }
-
-       while ((map[i].rfmax * 1000) < *freq) {
-               if (map[i + 1].rfmax == 0) {
-                       tda_map("%s: frequency (%d) out of range\n",
-                               map_name, *freq);
-                       ret = -ERANGE;
-                       break;
-               }
-               i++;
-       }
-       *val = map[i].val;
-
-       tda_map("(%d) %s: 0x%02x\n", i, map_name, *val);
-fail:
-       return ret;
-}
-
-/*---------------------------------------------------------------------*/
-
-static struct tda18271_std_map tda18271c1_std_map = {
-       .fm_radio = { .if_freq = 1250, .fm_rfn = 1, .agc_mode = 3, .std = 0,
-                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x18 */
-       .atv_b    = { .if_freq = 6750, .fm_rfn = 0, .agc_mode = 1, .std = 6,
-                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
-       .atv_dk   = { .if_freq = 7750, .fm_rfn = 0, .agc_mode = 1, .std = 7,
-                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
-       .atv_gh   = { .if_freq = 7750, .fm_rfn = 0, .agc_mode = 1, .std = 7,
-                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
-       .atv_i    = { .if_freq = 7750, .fm_rfn = 0, .agc_mode = 1, .std = 7,
-                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
-       .atv_l    = { .if_freq = 7750, .fm_rfn = 0, .agc_mode = 1, .std = 7,
-                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
-       .atv_lc   = { .if_freq = 1250, .fm_rfn = 0, .agc_mode = 1, .std = 7,
-                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
-       .atv_mn   = { .if_freq = 5750, .fm_rfn = 0, .agc_mode = 1, .std = 5,
-                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0d */
-       .atsc_6   = { .if_freq = 3250, .fm_rfn = 0, .agc_mode = 3, .std = 4,
-                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
-       .dvbt_6   = { .if_freq = 3300, .fm_rfn = 0, .agc_mode = 3, .std = 4,
-                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
-       .dvbt_7   = { .if_freq = 3800, .fm_rfn = 0, .agc_mode = 3, .std = 5,
-                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1d */
-       .dvbt_8   = { .if_freq = 4300, .fm_rfn = 0, .agc_mode = 3, .std = 6,
-                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1e */
-       .qam_6    = { .if_freq = 4000, .fm_rfn = 0, .agc_mode = 3, .std = 5,
-                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1d */
-       .qam_7    = { .if_freq = 4500, .fm_rfn = 0, .agc_mode = 3, .std = 6,
-                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1e */
-       .qam_8    = { .if_freq = 5000, .fm_rfn = 0, .agc_mode = 3, .std = 7,
-                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1f */
-};
-
-static struct tda18271_std_map tda18271c2_std_map = {
-       .fm_radio = { .if_freq = 1250, .fm_rfn = 1, .agc_mode = 3, .std = 0,
-                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x18 */
-       .atv_b    = { .if_freq = 6000, .fm_rfn = 0, .agc_mode = 1, .std = 5,
-                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0d */
-       .atv_dk   = { .if_freq = 6900, .fm_rfn = 0, .agc_mode = 1, .std = 6,
-                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
-       .atv_gh   = { .if_freq = 7100, .fm_rfn = 0, .agc_mode = 1, .std = 6,
-                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
-       .atv_i    = { .if_freq = 7250, .fm_rfn = 0, .agc_mode = 1, .std = 6,
-                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
-       .atv_l    = { .if_freq = 6900, .fm_rfn = 0, .agc_mode = 1, .std = 6,
-                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
-       .atv_lc   = { .if_freq = 1250, .fm_rfn = 0, .agc_mode = 1, .std = 6,
-                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
-       .atv_mn   = { .if_freq = 5400, .fm_rfn = 0, .agc_mode = 1, .std = 4,
-                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0c */
-       .atsc_6   = { .if_freq = 3250, .fm_rfn = 0, .agc_mode = 3, .std = 4,
-                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
-       .dvbt_6   = { .if_freq = 3300, .fm_rfn = 0, .agc_mode = 3, .std = 4,
-                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
-       .dvbt_7   = { .if_freq = 3500, .fm_rfn = 0, .agc_mode = 3, .std = 4,
-                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
-       .dvbt_8   = { .if_freq = 4000, .fm_rfn = 0, .agc_mode = 3, .std = 5,
-                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1d */
-       .qam_6    = { .if_freq = 4000, .fm_rfn = 0, .agc_mode = 3, .std = 5,
-                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1d */
-       .qam_7    = { .if_freq = 4500, .fm_rfn = 0, .agc_mode = 3, .std = 6,
-                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1e */
-       .qam_8    = { .if_freq = 5000, .fm_rfn = 0, .agc_mode = 3, .std = 7,
-                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1f */
-};
-
-/*---------------------------------------------------------------------*/
-
-static struct tda18271_map_layout tda18271c1_map_layout = {
-       .main_pll          = tda18271c1_main_pll,
-       .cal_pll           = tda18271c1_cal_pll,
-
-       .rf_cal            = tda18271c1_rf_cal,
-       .rf_cal_kmco       = tda18271c1_km,
-
-       .bp_filter         = tda18271_bp_filter,
-       .rf_band           = tda18271_rf_band,
-       .gain_taper        = tda18271_gain_taper,
-       .ir_measure        = tda18271_ir_measure,
-};
-
-static struct tda18271_map_layout tda18271c2_map_layout = {
-       .main_pll          = tda18271c2_main_pll,
-       .cal_pll           = tda18271c2_cal_pll,
-
-       .rf_cal            = tda18271c2_rf_cal,
-       .rf_cal_kmco       = tda18271c2_km,
-
-       .rf_cal_dc_over_dt = tda18271_rf_cal_dc_over_dt,
-
-       .bp_filter         = tda18271_bp_filter,
-       .rf_band           = tda18271_rf_band,
-       .gain_taper        = tda18271_gain_taper,
-       .ir_measure        = tda18271_ir_measure,
-};
-
-int tda18271_assign_map_layout(struct dvb_frontend *fe)
-{
-       struct tda18271_priv *priv = fe->tuner_priv;
-       int ret = 0;
-
-       switch (priv->id) {
-       case TDA18271HDC1:
-               priv->maps = &tda18271c1_map_layout;
-               memcpy(&priv->std, &tda18271c1_std_map,
-                      sizeof(struct tda18271_std_map));
-               break;
-       case TDA18271HDC2:
-               priv->maps = &tda18271c2_map_layout;
-               memcpy(&priv->std, &tda18271c2_std_map,
-                      sizeof(struct tda18271_std_map));
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
-       memcpy(priv->rf_cal_state, &tda18271_rf_band_template,
-              sizeof(tda18271_rf_band_template));
-
-       return ret;
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h
deleted file mode 100644 (file)
index 454c152..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
-    tda18271-priv.h - private header for the NXP TDA18271 silicon tuner
-
-    Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
-
-    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 __TDA18271_PRIV_H__
-#define __TDA18271_PRIV_H__
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/mutex.h>
-#include "tuner-i2c.h"
-#include "tda18271.h"
-
-#define R_ID     0x00  /* ID byte                */
-#define R_TM     0x01  /* Thermo byte            */
-#define R_PL     0x02  /* Power level byte       */
-#define R_EP1    0x03  /* Easy Prog byte 1       */
-#define R_EP2    0x04  /* Easy Prog byte 2       */
-#define R_EP3    0x05  /* Easy Prog byte 3       */
-#define R_EP4    0x06  /* Easy Prog byte 4       */
-#define R_EP5    0x07  /* Easy Prog byte 5       */
-#define R_CPD    0x08  /* Cal Post-Divider byte  */
-#define R_CD1    0x09  /* Cal Divider byte 1     */
-#define R_CD2    0x0a  /* Cal Divider byte 2     */
-#define R_CD3    0x0b  /* Cal Divider byte 3     */
-#define R_MPD    0x0c  /* Main Post-Divider byte */
-#define R_MD1    0x0d  /* Main Divider byte 1    */
-#define R_MD2    0x0e  /* Main Divider byte 2    */
-#define R_MD3    0x0f  /* Main Divider byte 3    */
-#define R_EB1    0x10  /* Extended byte 1        */
-#define R_EB2    0x11  /* Extended byte 2        */
-#define R_EB3    0x12  /* Extended byte 3        */
-#define R_EB4    0x13  /* Extended byte 4        */
-#define R_EB5    0x14  /* Extended byte 5        */
-#define R_EB6    0x15  /* Extended byte 6        */
-#define R_EB7    0x16  /* Extended byte 7        */
-#define R_EB8    0x17  /* Extended byte 8        */
-#define R_EB9    0x18  /* Extended byte 9        */
-#define R_EB10   0x19  /* Extended byte 10       */
-#define R_EB11   0x1a  /* Extended byte 11       */
-#define R_EB12   0x1b  /* Extended byte 12       */
-#define R_EB13   0x1c  /* Extended byte 13       */
-#define R_EB14   0x1d  /* Extended byte 14       */
-#define R_EB15   0x1e  /* Extended byte 15       */
-#define R_EB16   0x1f  /* Extended byte 16       */
-#define R_EB17   0x20  /* Extended byte 17       */
-#define R_EB18   0x21  /* Extended byte 18       */
-#define R_EB19   0x22  /* Extended byte 19       */
-#define R_EB20   0x23  /* Extended byte 20       */
-#define R_EB21   0x24  /* Extended byte 21       */
-#define R_EB22   0x25  /* Extended byte 22       */
-#define R_EB23   0x26  /* Extended byte 23       */
-
-#define TDA18271_NUM_REGS 39
-
-/*---------------------------------------------------------------------*/
-
-struct tda18271_rf_tracking_filter_cal {
-       u32 rfmax;
-       u8  rfband;
-       u32 rf1_def;
-       u32 rf2_def;
-       u32 rf3_def;
-       u32 rf1;
-       u32 rf2;
-       u32 rf3;
-       s32 rf_a1;
-       s32 rf_b1;
-       s32 rf_a2;
-       s32 rf_b2;
-};
-
-enum tda18271_pll {
-       TDA18271_MAIN_PLL,
-       TDA18271_CAL_PLL,
-};
-
-struct tda18271_map_layout;
-
-enum tda18271_ver {
-       TDA18271HDC1,
-       TDA18271HDC2,
-};
-
-struct tda18271_priv {
-       unsigned char tda18271_regs[TDA18271_NUM_REGS];
-
-       struct list_head        hybrid_tuner_instance_list;
-       struct tuner_i2c_props  i2c_props;
-
-       enum tda18271_mode mode;
-       enum tda18271_role role;
-       enum tda18271_i2c_gate gate;
-       enum tda18271_ver id;
-       enum tda18271_output_options output_opt;
-       enum tda18271_small_i2c small_i2c;
-
-       unsigned int config; /* interface to saa713x / tda829x */
-       unsigned int cal_initialized:1;
-
-       u8 tm_rfcal;
-
-       struct tda18271_map_layout *maps;
-       struct tda18271_std_map std;
-       struct tda18271_rf_tracking_filter_cal rf_cal_state[8];
-
-       struct mutex lock;
-
-       u16 if_freq;
-
-       u32 frequency;
-       u32 bandwidth;
-};
-
-/*---------------------------------------------------------------------*/
-
-extern int tda18271_debug;
-
-#define DBG_INFO 1
-#define DBG_MAP  2
-#define DBG_REG  4
-#define DBG_ADV  8
-#define DBG_CAL  16
-
-__attribute__((format(printf, 4, 5)))
-int _tda_printk(struct tda18271_priv *state, const char *level,
-               const char *func, const char *fmt, ...);
-
-#define tda_printk(st, lvl, fmt, arg...)                       \
-       _tda_printk(st, lvl, __func__, fmt, ##arg)
-
-#define tda_dprintk(st, lvl, fmt, arg...)                      \
-do {                                                           \
-       if (tda18271_debug & lvl)                               \
-               tda_printk(st, KERN_DEBUG, fmt, ##arg);         \
-} while (0)
-
-#define tda_info(fmt, arg...)  pr_info(fmt, ##arg)
-#define tda_warn(fmt, arg...)  tda_printk(priv, KERN_WARNING, fmt, ##arg)
-#define tda_err(fmt, arg...)   tda_printk(priv, KERN_ERR,     fmt, ##arg)
-#define tda_dbg(fmt, arg...)   tda_dprintk(priv, DBG_INFO,    fmt, ##arg)
-#define tda_map(fmt, arg...)   tda_dprintk(priv, DBG_MAP,     fmt, ##arg)
-#define tda_reg(fmt, arg...)   tda_dprintk(priv, DBG_REG,     fmt, ##arg)
-#define tda_cal(fmt, arg...)   tda_dprintk(priv, DBG_CAL,     fmt, ##arg)
-
-#define tda_fail(ret)                                                       \
-({                                                                          \
-       int __ret;                                                           \
-       __ret = (ret < 0);                                                   \
-       if (__ret)                                                           \
-               tda_printk(priv, KERN_ERR,                                   \
-                          "error %d on line %d\n", ret, __LINE__);          \
-       __ret;                                                               \
-})
-
-/*---------------------------------------------------------------------*/
-
-enum tda18271_map_type {
-       /* tda18271_pll_map */
-       MAIN_PLL,
-       CAL_PLL,
-       /* tda18271_map */
-       RF_CAL,
-       RF_CAL_KMCO,
-       RF_CAL_DC_OVER_DT,
-       BP_FILTER,
-       RF_BAND,
-       GAIN_TAPER,
-       IR_MEASURE,
-};
-
-extern int tda18271_lookup_pll_map(struct dvb_frontend *fe,
-                                  enum tda18271_map_type map_type,
-                                  u32 *freq, u8 *post_div, u8 *div);
-extern int tda18271_lookup_map(struct dvb_frontend *fe,
-                              enum tda18271_map_type map_type,
-                              u32 *freq, u8 *val);
-
-extern int tda18271_lookup_thermometer(struct dvb_frontend *fe);
-
-extern int tda18271_lookup_rf_band(struct dvb_frontend *fe,
-                                  u32 *freq, u8 *rf_band);
-
-extern int tda18271_lookup_cid_target(struct dvb_frontend *fe,
-                                     u32 *freq, u8 *cid_target,
-                                     u16 *count_limit);
-
-extern int tda18271_assign_map_layout(struct dvb_frontend *fe);
-
-/*---------------------------------------------------------------------*/
-
-extern int tda18271_read_regs(struct dvb_frontend *fe);
-extern int tda18271_read_extended(struct dvb_frontend *fe);
-extern int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len);
-extern int tda18271_init_regs(struct dvb_frontend *fe);
-
-extern int tda18271_charge_pump_source(struct dvb_frontend *fe,
-                                      enum tda18271_pll pll, int force);
-extern int tda18271_set_standby_mode(struct dvb_frontend *fe,
-                                    int sm, int sm_lt, int sm_xt);
-
-extern int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq);
-extern int tda18271_calc_cal_pll(struct dvb_frontend *fe, u32 freq);
-
-extern int tda18271_calc_bp_filter(struct dvb_frontend *fe, u32 *freq);
-extern int tda18271_calc_km(struct dvb_frontend *fe, u32 *freq);
-extern int tda18271_calc_rf_band(struct dvb_frontend *fe, u32 *freq);
-extern int tda18271_calc_gain_taper(struct dvb_frontend *fe, u32 *freq);
-extern int tda18271_calc_ir_measure(struct dvb_frontend *fe, u32 *freq);
-extern int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq);
-
-#endif /* __TDA18271_PRIV_H__ */
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/common/tuners/tda18271.h b/drivers/media/common/tuners/tda18271.h
deleted file mode 100644 (file)
index 640bae4..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
-    tda18271.h - header for the Philips / NXP TDA18271 silicon tuner
-
-    Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
-
-    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 __TDA18271_H__
-#define __TDA18271_H__
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-
-struct tda18271_std_map_item {
-       u16 if_freq;
-
-       /* EP3[4:3] */
-       unsigned int agc_mode:2;
-       /* EP3[2:0] */
-       unsigned int std:3;
-       /* EP4[7] */
-       unsigned int fm_rfn:1;
-       /* EP4[4:2] */
-       unsigned int if_lvl:3;
-       /* EB22[6:0] */
-       unsigned int rfagc_top:7;
-};
-
-struct tda18271_std_map {
-       struct tda18271_std_map_item fm_radio;
-       struct tda18271_std_map_item atv_b;
-       struct tda18271_std_map_item atv_dk;
-       struct tda18271_std_map_item atv_gh;
-       struct tda18271_std_map_item atv_i;
-       struct tda18271_std_map_item atv_l;
-       struct tda18271_std_map_item atv_lc;
-       struct tda18271_std_map_item atv_mn;
-       struct tda18271_std_map_item atsc_6;
-       struct tda18271_std_map_item dvbt_6;
-       struct tda18271_std_map_item dvbt_7;
-       struct tda18271_std_map_item dvbt_8;
-       struct tda18271_std_map_item qam_6;
-       struct tda18271_std_map_item qam_7;
-       struct tda18271_std_map_item qam_8;
-};
-
-enum tda18271_role {
-       TDA18271_MASTER = 0,
-       TDA18271_SLAVE,
-};
-
-enum tda18271_i2c_gate {
-       TDA18271_GATE_AUTO = 0,
-       TDA18271_GATE_ANALOG,
-       TDA18271_GATE_DIGITAL,
-};
-
-enum tda18271_output_options {
-       /* slave tuner output & loop thru & xtal oscillator always on */
-       TDA18271_OUTPUT_LT_XT_ON = 0,
-
-       /* slave tuner output loop thru off */
-       TDA18271_OUTPUT_LT_OFF = 1,
-
-       /* xtal oscillator off */
-       TDA18271_OUTPUT_XT_OFF = 2,
-};
-
-enum tda18271_small_i2c {
-       TDA18271_39_BYTE_CHUNK_INIT = 0,
-       TDA18271_16_BYTE_CHUNK_INIT = 16,
-       TDA18271_08_BYTE_CHUNK_INIT = 8,
-       TDA18271_03_BYTE_CHUNK_INIT = 3,
-};
-
-struct tda18271_config {
-       /* override default if freq / std settings (optional) */
-       struct tda18271_std_map *std_map;
-
-       /* master / slave tuner: master uses main pll, slave uses cal pll */
-       enum tda18271_role role;
-
-       /* use i2c gate provided by analog or digital demod */
-       enum tda18271_i2c_gate gate;
-
-       /* output options that can be disabled */
-       enum tda18271_output_options output_opt;
-
-       /* some i2c providers can't write all 39 registers at once */
-       enum tda18271_small_i2c small_i2c;
-
-       /* force rf tracking filter calibration on startup */
-       unsigned int rf_cal_on_startup:1;
-
-       /* interface to saa713x / tda829x */
-       unsigned int config;
-};
-
-#define TDA18271_CALLBACK_CMD_AGC_ENABLE 0
-
-enum tda18271_mode {
-       TDA18271_ANALOG = 0,
-       TDA18271_DIGITAL,
-};
-
-#if defined(CONFIG_MEDIA_TUNER_TDA18271) || (defined(CONFIG_MEDIA_TUNER_TDA18271_MODULE) && defined(MODULE))
-extern struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
-                                           struct i2c_adapter *i2c,
-                                           struct tda18271_config *cfg);
-#else
-static inline struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe,
-                                                  u8 addr,
-                                                  struct i2c_adapter *i2c,
-                                                  struct tda18271_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* __TDA18271_H__ */
diff --git a/drivers/media/common/tuners/tda827x.c b/drivers/media/common/tuners/tda827x.c
deleted file mode 100644 (file)
index a0d1762..0000000
+++ /dev/null
@@ -1,917 +0,0 @@
-/*
- *
- * (c) 2005 Hartmut Hackmann
- * (c) 2007 Michael Krufky
- *
- *  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.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <asm/types.h>
-#include <linux/dvb/frontend.h>
-#include <linux/videodev2.h>
-
-#include "tda827x.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-#define dprintk(args...) \
-       do {                                        \
-               if (debug) printk(KERN_DEBUG "tda827x: " args); \
-       } while (0)
-
-struct tda827x_priv {
-       int i2c_addr;
-       struct i2c_adapter *i2c_adap;
-       struct tda827x_config *cfg;
-
-       unsigned int sgIF;
-       unsigned char lpsel;
-
-       u32 frequency;
-       u32 bandwidth;
-};
-
-static void tda827x_set_std(struct dvb_frontend *fe,
-                           struct analog_parameters *params)
-{
-       struct tda827x_priv *priv = fe->tuner_priv;
-       char *mode;
-
-       priv->lpsel = 0;
-       if (params->std & V4L2_STD_MN) {
-               priv->sgIF = 92;
-               priv->lpsel = 1;
-               mode = "MN";
-       } else if (params->std & V4L2_STD_B) {
-               priv->sgIF = 108;
-               mode = "B";
-       } else if (params->std & V4L2_STD_GH) {
-               priv->sgIF = 124;
-               mode = "GH";
-       } else if (params->std & V4L2_STD_PAL_I) {
-               priv->sgIF = 124;
-               mode = "I";
-       } else if (params->std & V4L2_STD_DK) {
-               priv->sgIF = 124;
-               mode = "DK";
-       } else if (params->std & V4L2_STD_SECAM_L) {
-               priv->sgIF = 124;
-               mode = "L";
-       } else if (params->std & V4L2_STD_SECAM_LC) {
-               priv->sgIF = 20;
-               mode = "LC";
-       } else {
-               priv->sgIF = 124;
-               mode = "xx";
-       }
-
-       if (params->mode == V4L2_TUNER_RADIO) {
-               priv->sgIF = 88; /* if frequency is 5.5 MHz */
-               dprintk("setting tda827x to radio FM\n");
-       } else
-               dprintk("setting tda827x to system %s\n", mode);
-}
-
-
-/* ------------------------------------------------------------------ */
-
-struct tda827x_data {
-       u32 lomax;
-       u8  spd;
-       u8  bs;
-       u8  bp;
-       u8  cp;
-       u8  gc3;
-       u8 div1p5;
-};
-
-static const struct tda827x_data tda827x_table[] = {
-       { .lomax =  62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
-       { .lomax =  66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
-       { .lomax =  76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
-       { .lomax =  84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
-       { .lomax =  93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
-       { .lomax =  98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
-       { .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
-       { .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
-       { .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
-       { .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
-       { .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
-       { .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0},
-       { .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
-       { .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
-       { .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
-       { .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
-       { .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
-       { .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
-       { .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
-       { .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
-       { .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
-       { .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
-       { .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
-       { .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
-       { .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
-       { .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
-       { .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
-       { .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
-       { .lomax =         0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}
-};
-
-static int tuner_transfer(struct dvb_frontend *fe,
-                         struct i2c_msg *msg,
-                         const int size)
-{
-       int rc;
-       struct tda827x_priv *priv = fe->tuner_priv;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-       rc = i2c_transfer(priv->i2c_adap, msg, size);
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0);
-
-       if (rc >= 0 && rc != size)
-               return -EIO;
-
-       return rc;
-}
-
-static int tda827xo_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct tda827x_priv *priv = fe->tuner_priv;
-       u8 buf[14];
-       int rc;
-
-       struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
-                              .buf = buf, .len = sizeof(buf) };
-       int i, tuner_freq, if_freq;
-       u32 N;
-
-       dprintk("%s:\n", __func__);
-       if (c->bandwidth_hz == 0) {
-               if_freq = 5000000;
-       } else if (c->bandwidth_hz <= 6000000) {
-               if_freq = 4000000;
-       } else if (c->bandwidth_hz <= 7000000) {
-               if_freq = 4500000;
-       } else {        /* 8 MHz */
-               if_freq = 5000000;
-       }
-       tuner_freq = c->frequency;
-
-       i = 0;
-       while (tda827x_table[i].lomax < tuner_freq) {
-               if (tda827x_table[i + 1].lomax == 0)
-                       break;
-               i++;
-       }
-
-       tuner_freq += if_freq;
-
-       N = ((tuner_freq + 125000) / 250000) << (tda827x_table[i].spd + 2);
-       buf[0] = 0;
-       buf[1] = (N>>8) | 0x40;
-       buf[2] = N & 0xff;
-       buf[3] = 0;
-       buf[4] = 0x52;
-       buf[5] = (tda827x_table[i].spd << 6) + (tda827x_table[i].div1p5 << 5) +
-                               (tda827x_table[i].bs << 3) +
-                               tda827x_table[i].bp;
-       buf[6] = (tda827x_table[i].gc3 << 4) + 0x8f;
-       buf[7] = 0xbf;
-       buf[8] = 0x2a;
-       buf[9] = 0x05;
-       buf[10] = 0xff;
-       buf[11] = 0x00;
-       buf[12] = 0x00;
-       buf[13] = 0x40;
-
-       msg.len = 14;
-       rc = tuner_transfer(fe, &msg, 1);
-       if (rc < 0)
-               goto err;
-
-       msleep(500);
-       /* correct CP value */
-       buf[0] = 0x30;
-       buf[1] = 0x50 + tda827x_table[i].cp;
-       msg.len = 2;
-
-       rc = tuner_transfer(fe, &msg, 1);
-       if (rc < 0)
-               goto err;
-
-       priv->frequency = c->frequency;
-       priv->bandwidth = c->bandwidth_hz;
-
-       return 0;
-
-err:
-       printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
-              __func__, priv->i2c_addr << 1);
-       return rc;
-}
-
-static int tda827xo_sleep(struct dvb_frontend *fe)
-{
-       struct tda827x_priv *priv = fe->tuner_priv;
-       static u8 buf[] = { 0x30, 0xd0 };
-       struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
-                              .buf = buf, .len = sizeof(buf) };
-
-       dprintk("%s:\n", __func__);
-       tuner_transfer(fe, &msg, 1);
-
-       if (priv->cfg && priv->cfg->sleep)
-               priv->cfg->sleep(fe);
-
-       return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int tda827xo_set_analog_params(struct dvb_frontend *fe,
-                                     struct analog_parameters *params)
-{
-       unsigned char tuner_reg[8];
-       unsigned char reg2[2];
-       u32 N;
-       int i;
-       struct tda827x_priv *priv = fe->tuner_priv;
-       struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0 };
-       unsigned int freq = params->frequency;
-
-       tda827x_set_std(fe, params);
-
-       if (params->mode == V4L2_TUNER_RADIO)
-               freq = freq / 1000;
-
-       N = freq + priv->sgIF;
-
-       i = 0;
-       while (tda827x_table[i].lomax < N * 62500) {
-               if (tda827x_table[i + 1].lomax == 0)
-                       break;
-               i++;
-       }
-
-       N = N << tda827x_table[i].spd;
-
-       tuner_reg[0] = 0;
-       tuner_reg[1] = (unsigned char)(N>>8);
-       tuner_reg[2] = (unsigned char) N;
-       tuner_reg[3] = 0x40;
-       tuner_reg[4] = 0x52 + (priv->lpsel << 5);
-       tuner_reg[5] = (tda827x_table[i].spd    << 6) +
-                      (tda827x_table[i].div1p5 << 5) +
-                      (tda827x_table[i].bs     << 3) + tda827x_table[i].bp;
-       tuner_reg[6] = 0x8f + (tda827x_table[i].gc3 << 4);
-       tuner_reg[7] = 0x8f;
-
-       msg.buf = tuner_reg;
-       msg.len = 8;
-       tuner_transfer(fe, &msg, 1);
-
-       msg.buf = reg2;
-       msg.len = 2;
-       reg2[0] = 0x80;
-       reg2[1] = 0;
-       tuner_transfer(fe, &msg, 1);
-
-       reg2[0] = 0x60;
-       reg2[1] = 0xbf;
-       tuner_transfer(fe, &msg, 1);
-
-       reg2[0] = 0x30;
-       reg2[1] = tuner_reg[4] + 0x80;
-       tuner_transfer(fe, &msg, 1);
-
-       msleep(1);
-       reg2[0] = 0x30;
-       reg2[1] = tuner_reg[4] + 4;
-       tuner_transfer(fe, &msg, 1);
-
-       msleep(1);
-       reg2[0] = 0x30;
-       reg2[1] = tuner_reg[4];
-       tuner_transfer(fe, &msg, 1);
-
-       msleep(550);
-       reg2[0] = 0x30;
-       reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp;
-       tuner_transfer(fe, &msg, 1);
-
-       reg2[0] = 0x60;
-       reg2[1] = 0x3f;
-       tuner_transfer(fe, &msg, 1);
-
-       reg2[0] = 0x80;
-       reg2[1] = 0x08;   /* Vsync en */
-       tuner_transfer(fe, &msg, 1);
-
-       priv->frequency = params->frequency;
-
-       return 0;
-}
-
-static void tda827xo_agcf(struct dvb_frontend *fe)
-{
-       struct tda827x_priv *priv = fe->tuner_priv;
-       unsigned char data[] = { 0x80, 0x0c };
-       struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
-                              .buf = data, .len = 2};
-
-       tuner_transfer(fe, &msg, 1);
-}
-
-/* ------------------------------------------------------------------ */
-
-struct tda827xa_data {
-       u32 lomax;
-       u8  svco;
-       u8  spd;
-       u8  scr;
-       u8  sbs;
-       u8  gc3;
-};
-
-static struct tda827xa_data tda827xa_dvbt[] = {
-       { .lomax =  56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
-       { .lomax =  67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
-       { .lomax =  81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
-       { .lomax =  97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
-       { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
-       { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
-       { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
-       { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
-       { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
-       { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
-       { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
-       { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
-       { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
-       { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
-       { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
-       { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
-       { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
-       { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
-       { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
-       { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
-       { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
-       { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
-       { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
-       { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
-       { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
-       { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
-       { .lomax =         0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
-};
-
-static struct tda827xa_data tda827xa_dvbc[] = {
-       { .lomax =  50125000, .svco = 2, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
-       { .lomax =  58500000, .svco = 3, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
-       { .lomax =  69250000, .svco = 0, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
-       { .lomax =  83625000, .svco = 1, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
-       { .lomax =  97500000, .svco = 2, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
-       { .lomax = 100250000, .svco = 2, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
-       { .lomax = 117000000, .svco = 3, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
-       { .lomax = 138500000, .svco = 0, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
-       { .lomax = 167250000, .svco = 1, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
-       { .lomax = 187000000, .svco = 2, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
-       { .lomax = 200500000, .svco = 2, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 1},
-       { .lomax = 234000000, .svco = 3, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 3},
-       { .lomax = 277000000, .svco = 0, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 3},
-       { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 1},
-       { .lomax = 334500000, .svco = 1, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
-       { .lomax = 401000000, .svco = 2, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
-       { .lomax = 468000000, .svco = 3, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 1},
-       { .lomax = 535000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
-       { .lomax = 554000000, .svco = 0, .spd = 0, .scr = 2, .sbs = 3, .gc3 = 1},
-       { .lomax = 638000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
-       { .lomax = 669000000, .svco = 1, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
-       { .lomax = 720000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
-       { .lomax = 802000000, .svco = 2, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
-       { .lomax = 835000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
-       { .lomax = 885000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
-       { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
-       { .lomax =         0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
-};
-
-static struct tda827xa_data tda827xa_analog[] = {
-       { .lomax =  56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3},
-       { .lomax =  67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
-       { .lomax =  81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
-       { .lomax =  97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
-       { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
-       { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
-       { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
-       { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
-       { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
-       { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
-       { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3},
-       { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3},
-       { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
-       { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
-       { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
-       { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
-       { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
-       { .lomax = 554000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
-       { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
-       { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
-       { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
-       { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
-       { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
-       { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
-       { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
-       { .lomax =         0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
-};
-
-static int tda827xa_sleep(struct dvb_frontend *fe)
-{
-       struct tda827x_priv *priv = fe->tuner_priv;
-       static u8 buf[] = { 0x30, 0x90 };
-       struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
-                              .buf = buf, .len = sizeof(buf) };
-
-       dprintk("%s:\n", __func__);
-
-       tuner_transfer(fe, &msg, 1);
-
-       if (priv->cfg && priv->cfg->sleep)
-               priv->cfg->sleep(fe);
-
-       return 0;
-}
-
-static void tda827xa_lna_gain(struct dvb_frontend *fe, int high,
-                             struct analog_parameters *params)
-{
-       struct tda827x_priv *priv = fe->tuner_priv;
-       unsigned char buf[] = {0x22, 0x01};
-       int arg;
-       int gp_func;
-       struct i2c_msg msg = { .flags = 0, .buf = buf, .len = sizeof(buf) };
-
-       if (NULL == priv->cfg) {
-               dprintk("tda827x_config not defined, cannot set LNA gain!\n");
-               return;
-       }
-       msg.addr = priv->cfg->switch_addr;
-       if (priv->cfg->config) {
-               if (high)
-                       dprintk("setting LNA to high gain\n");
-               else
-                       dprintk("setting LNA to low gain\n");
-       }
-       switch (priv->cfg->config) {
-       case 0: /* no LNA */
-               break;
-       case 1: /* switch is GPIO 0 of tda8290 */
-       case 2:
-               if (params == NULL) {
-                       gp_func = 0;
-                       arg  = 0;
-               } else {
-                       /* turn Vsync on */
-                       gp_func = 1;
-                       if (params->std & V4L2_STD_MN)
-                               arg = 1;
-                       else
-                               arg = 0;
-               }
-               if (fe->callback)
-                       fe->callback(priv->i2c_adap->algo_data,
-                                    DVB_FRONTEND_COMPONENT_TUNER,
-                                    gp_func, arg);
-               buf[1] = high ? 0 : 1;
-               if (priv->cfg->config == 2)
-                       buf[1] = high ? 1 : 0;
-               tuner_transfer(fe, &msg, 1);
-               break;
-       case 3: /* switch with GPIO of saa713x */
-               if (fe->callback)
-                       fe->callback(priv->i2c_adap->algo_data,
-                                    DVB_FRONTEND_COMPONENT_TUNER, 0, high);
-               break;
-       }
-}
-
-static int tda827xa_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       struct tda827x_priv *priv = fe->tuner_priv;
-       struct tda827xa_data *frequency_map = tda827xa_dvbt;
-       u8 buf[11];
-
-       struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
-                              .buf = buf, .len = sizeof(buf) };
-
-       int i, tuner_freq, if_freq, rc;
-       u32 N;
-
-       dprintk("%s:\n", __func__);
-
-       tda827xa_lna_gain(fe, 1, NULL);
-       msleep(20);
-
-       if (c->bandwidth_hz == 0) {
-               if_freq = 5000000;
-       } else if (c->bandwidth_hz <= 6000000) {
-               if_freq = 4000000;
-       } else if (c->bandwidth_hz <= 7000000) {
-               if_freq = 4500000;
-       } else {        /* 8 MHz */
-               if_freq = 5000000;
-       }
-       tuner_freq = c->frequency;
-
-       switch (c->delivery_system) {
-       case SYS_DVBC_ANNEX_A:
-       case SYS_DVBC_ANNEX_C:
-               dprintk("%s select tda827xa_dvbc\n", __func__);
-               frequency_map = tda827xa_dvbc;
-               break;
-       default:
-               break;
-       }
-
-       i = 0;
-       while (frequency_map[i].lomax < tuner_freq) {
-               if (frequency_map[i + 1].lomax == 0)
-                       break;
-               i++;
-       }
-
-       tuner_freq += if_freq;
-
-       N = ((tuner_freq + 31250) / 62500) << frequency_map[i].spd;
-       buf[0] = 0;            // subaddress
-       buf[1] = N >> 8;
-       buf[2] = N & 0xff;
-       buf[3] = 0;
-       buf[4] = 0x16;
-       buf[5] = (frequency_map[i].spd << 5) + (frequency_map[i].svco << 3) +
-                       frequency_map[i].sbs;
-       buf[6] = 0x4b + (frequency_map[i].gc3 << 4);
-       buf[7] = 0x1c;
-       buf[8] = 0x06;
-       buf[9] = 0x24;
-       buf[10] = 0x00;
-       msg.len = 11;
-       rc = tuner_transfer(fe, &msg, 1);
-       if (rc < 0)
-               goto err;
-
-       buf[0] = 0x90;
-       buf[1] = 0xff;
-       buf[2] = 0x60;
-       buf[3] = 0x00;
-       buf[4] = 0x59;  // lpsel, for 6MHz + 2
-       msg.len = 5;
-       rc = tuner_transfer(fe, &msg, 1);
-       if (rc < 0)
-               goto err;
-
-       buf[0] = 0xa0;
-       buf[1] = 0x40;
-       msg.len = 2;
-       rc = tuner_transfer(fe, &msg, 1);
-       if (rc < 0)
-               goto err;
-
-       msleep(11);
-       msg.flags = I2C_M_RD;
-       rc = tuner_transfer(fe, &msg, 1);
-       if (rc < 0)
-               goto err;
-       msg.flags = 0;
-
-       buf[1] >>= 4;
-       dprintk("tda8275a AGC2 gain is: %d\n", buf[1]);
-       if ((buf[1]) < 2) {
-               tda827xa_lna_gain(fe, 0, NULL);
-               buf[0] = 0x60;
-               buf[1] = 0x0c;
-               rc = tuner_transfer(fe, &msg, 1);
-               if (rc < 0)
-                       goto err;
-       }
-
-       buf[0] = 0xc0;
-       buf[1] = 0x99;    // lpsel, for 6MHz + 2
-       rc = tuner_transfer(fe, &msg, 1);
-       if (rc < 0)
-               goto err;
-
-       buf[0] = 0x60;
-       buf[1] = 0x3c;
-       rc = tuner_transfer(fe, &msg, 1);
-       if (rc < 0)
-               goto err;
-
-       /* correct CP value */
-       buf[0] = 0x30;
-       buf[1] = 0x10 + frequency_map[i].scr;
-       rc = tuner_transfer(fe, &msg, 1);
-       if (rc < 0)
-               goto err;
-
-       msleep(163);
-       buf[0] = 0xc0;
-       buf[1] = 0x39;  // lpsel, for 6MHz + 2
-       rc = tuner_transfer(fe, &msg, 1);
-       if (rc < 0)
-               goto err;
-
-       msleep(3);
-       /* freeze AGC1 */
-       buf[0] = 0x50;
-       buf[1] = 0x4f + (frequency_map[i].gc3 << 4);
-       rc = tuner_transfer(fe, &msg, 1);
-       if (rc < 0)
-               goto err;
-
-       priv->frequency = c->frequency;
-       priv->bandwidth = c->bandwidth_hz;
-
-       return 0;
-
-err:
-       printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
-              __func__, priv->i2c_addr << 1);
-       return rc;
-}
-
-
-static int tda827xa_set_analog_params(struct dvb_frontend *fe,
-                                     struct analog_parameters *params)
-{
-       unsigned char tuner_reg[11];
-       u32 N;
-       int i;
-       struct tda827x_priv *priv = fe->tuner_priv;
-       struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
-                              .buf = tuner_reg, .len = sizeof(tuner_reg) };
-       unsigned int freq = params->frequency;
-
-       tda827x_set_std(fe, params);
-
-       tda827xa_lna_gain(fe, 1, params);
-       msleep(10);
-
-       if (params->mode == V4L2_TUNER_RADIO)
-               freq = freq / 1000;
-
-       N = freq + priv->sgIF;
-
-       i = 0;
-       while (tda827xa_analog[i].lomax < N * 62500) {
-               if (tda827xa_analog[i + 1].lomax == 0)
-                       break;
-               i++;
-       }
-
-       N = N << tda827xa_analog[i].spd;
-
-       tuner_reg[0] = 0;
-       tuner_reg[1] = (unsigned char)(N>>8);
-       tuner_reg[2] = (unsigned char) N;
-       tuner_reg[3] = 0;
-       tuner_reg[4] = 0x16;
-       tuner_reg[5] = (tda827xa_analog[i].spd << 5) +
-                      (tda827xa_analog[i].svco << 3) +
-                       tda827xa_analog[i].sbs;
-       tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4);
-       tuner_reg[7] = 0x1c;
-       tuner_reg[8] = 4;
-       tuner_reg[9] = 0x20;
-       tuner_reg[10] = 0x00;
-       msg.len = 11;
-       tuner_transfer(fe, &msg, 1);
-
-       tuner_reg[0] = 0x90;
-       tuner_reg[1] = 0xff;
-       tuner_reg[2] = 0xe0;
-       tuner_reg[3] = 0;
-       tuner_reg[4] = 0x99 + (priv->lpsel << 1);
-       msg.len = 5;
-       tuner_transfer(fe, &msg, 1);
-
-       tuner_reg[0] = 0xa0;
-       tuner_reg[1] = 0xc0;
-       msg.len = 2;
-       tuner_transfer(fe, &msg, 1);
-
-       tuner_reg[0] = 0x30;
-       tuner_reg[1] = 0x10 + tda827xa_analog[i].scr;
-       tuner_transfer(fe, &msg, 1);
-
-       msg.flags = I2C_M_RD;
-       tuner_transfer(fe, &msg, 1);
-       msg.flags = 0;
-       tuner_reg[1] >>= 4;
-       dprintk("AGC2 gain is: %d\n", tuner_reg[1]);
-       if (tuner_reg[1] < 1)
-               tda827xa_lna_gain(fe, 0, params);
-
-       msleep(100);
-       tuner_reg[0] = 0x60;
-       tuner_reg[1] = 0x3c;
-       tuner_transfer(fe, &msg, 1);
-
-       msleep(163);
-       tuner_reg[0] = 0x50;
-       tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
-       tuner_transfer(fe, &msg, 1);
-
-       tuner_reg[0] = 0x80;
-       tuner_reg[1] = 0x28;
-       tuner_transfer(fe, &msg, 1);
-
-       tuner_reg[0] = 0xb0;
-       tuner_reg[1] = 0x01;
-       tuner_transfer(fe, &msg, 1);
-
-       tuner_reg[0] = 0xc0;
-       tuner_reg[1] = 0x19 + (priv->lpsel << 1);
-       tuner_transfer(fe, &msg, 1);
-
-       priv->frequency = params->frequency;
-
-       return 0;
-}
-
-static void tda827xa_agcf(struct dvb_frontend *fe)
-{
-       struct tda827x_priv *priv = fe->tuner_priv;
-       unsigned char data[] = {0x80, 0x2c};
-       struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0,
-                             .buf = data, .len = 2};
-       tuner_transfer(fe, &msg, 1);
-}
-
-/* ------------------------------------------------------------------ */
-
-static int tda827x_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static int tda827x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct tda827x_priv *priv = fe->tuner_priv;
-       *frequency = priv->frequency;
-       return 0;
-}
-
-static int tda827x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct tda827x_priv *priv = fe->tuner_priv;
-       *bandwidth = priv->bandwidth;
-       return 0;
-}
-
-static int tda827x_init(struct dvb_frontend *fe)
-{
-       struct tda827x_priv *priv = fe->tuner_priv;
-       dprintk("%s:\n", __func__);
-       if (priv->cfg && priv->cfg->init)
-               priv->cfg->init(fe);
-
-       return 0;
-}
-
-static int tda827x_probe_version(struct dvb_frontend *fe);
-
-static int tda827x_initial_init(struct dvb_frontend *fe)
-{
-       int ret;
-       ret = tda827x_probe_version(fe);
-       if (ret)
-               return ret;
-       return fe->ops.tuner_ops.init(fe);
-}
-
-static int tda827x_initial_sleep(struct dvb_frontend *fe)
-{
-       int ret;
-       ret = tda827x_probe_version(fe);
-       if (ret)
-               return ret;
-       return fe->ops.tuner_ops.sleep(fe);
-}
-
-static struct dvb_tuner_ops tda827xo_tuner_ops = {
-       .info = {
-               .name = "Philips TDA827X",
-               .frequency_min  =  55000000,
-               .frequency_max  = 860000000,
-               .frequency_step =    250000
-       },
-       .release = tda827x_release,
-       .init = tda827x_initial_init,
-       .sleep = tda827x_initial_sleep,
-       .set_params = tda827xo_set_params,
-       .set_analog_params = tda827xo_set_analog_params,
-       .get_frequency = tda827x_get_frequency,
-       .get_bandwidth = tda827x_get_bandwidth,
-};
-
-static struct dvb_tuner_ops tda827xa_tuner_ops = {
-       .info = {
-               .name = "Philips TDA827XA",
-               .frequency_min  =  44000000,
-               .frequency_max  = 906000000,
-               .frequency_step =     62500
-       },
-       .release = tda827x_release,
-       .init = tda827x_init,
-       .sleep = tda827xa_sleep,
-       .set_params = tda827xa_set_params,
-       .set_analog_params = tda827xa_set_analog_params,
-       .get_frequency = tda827x_get_frequency,
-       .get_bandwidth = tda827x_get_bandwidth,
-};
-
-static int tda827x_probe_version(struct dvb_frontend *fe)
-{
-       u8 data;
-       int rc;
-       struct tda827x_priv *priv = fe->tuner_priv;
-       struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD,
-                              .buf = &data, .len = 1 };
-
-       rc = tuner_transfer(fe, &msg, 1);
-
-       if (rc < 0) {
-               printk("%s: could not read from tuner at addr: 0x%02x\n",
-                      __func__, msg.addr << 1);
-               return rc;
-       }
-       if ((data & 0x3c) == 0) {
-               dprintk("tda827x tuner found\n");
-               fe->ops.tuner_ops.init  = tda827x_init;
-               fe->ops.tuner_ops.sleep = tda827xo_sleep;
-               if (priv->cfg)
-                       priv->cfg->agcf = tda827xo_agcf;
-       } else {
-               dprintk("tda827xa tuner found\n");
-               memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops));
-               if (priv->cfg)
-                       priv->cfg->agcf = tda827xa_agcf;
-       }
-       return 0;
-}
-
-struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr,
-                                   struct i2c_adapter *i2c,
-                                   struct tda827x_config *cfg)
-{
-       struct tda827x_priv *priv = NULL;
-
-       dprintk("%s:\n", __func__);
-       priv = kzalloc(sizeof(struct tda827x_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->i2c_addr = addr;
-       priv->i2c_adap = i2c;
-       priv->cfg = cfg;
-       memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops));
-       fe->tuner_priv = priv;
-
-       dprintk("type set to %s\n", fe->ops.tuner_ops.info.name);
-
-       return fe;
-}
-EXPORT_SYMBOL_GPL(tda827x_attach);
-
-MODULE_DESCRIPTION("DVB TDA827x driver");
-MODULE_AUTHOR("Hartmut Hackmann <hartmut.hackmann@t-online.de>");
-MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
-MODULE_LICENSE("GPL");
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/common/tuners/tda827x.h b/drivers/media/common/tuners/tda827x.h
deleted file mode 100644 (file)
index 7d72ce0..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-  /*
-     DVB Driver for Philips tda827x / tda827xa Silicon tuners
-
-     (c) 2005 Hartmut Hackmann
-     (c) 2007 Michael Krufky
-
-     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 __DVB_TDA827X_H__
-#define __DVB_TDA827X_H__
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-
-struct tda827x_config
-{
-       /* saa7134 - provided callbacks */
-       int (*init) (struct dvb_frontend *fe);
-       int (*sleep) (struct dvb_frontend *fe);
-
-       /* interface to tda829x driver */
-       unsigned int config;
-       int          switch_addr;
-
-       void (*agcf)(struct dvb_frontend *fe);
-};
-
-
-/**
- * Attach a tda827x tuner to the supplied frontend structure.
- *
- * @param fe Frontend to attach to.
- * @param addr i2c address of the tuner.
- * @param i2c i2c adapter to use.
- * @param cfg optional callback function pointers.
- * @return FE pointer on success, NULL on failure.
- */
-#if defined(CONFIG_MEDIA_TUNER_TDA827X) || (defined(CONFIG_MEDIA_TUNER_TDA827X_MODULE) && defined(MODULE))
-extern struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe, int addr,
-                                          struct i2c_adapter *i2c,
-                                          struct tda827x_config *cfg);
-#else
-static inline struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe,
-                                                 int addr,
-                                                 struct i2c_adapter *i2c,
-                                                 struct tda827x_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_MEDIA_TUNER_TDA827X
-
-#endif // __DVB_TDA827X_H__
diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c
deleted file mode 100644 (file)
index 8c48521..0000000
+++ /dev/null
@@ -1,874 +0,0 @@
-/*
-
-   i2c tv tuner chip device driver
-   controls the philips tda8290+75 tuner chip combo.
-
-   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.
-
-   This "tda8290" module was split apart from the original "tuner" module.
-*/
-
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/videodev2.h>
-#include "tuner-i2c.h"
-#include "tda8290.h"
-#include "tda827x.h"
-#include "tda18271.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable verbose debug messages");
-
-static int deemphasis_50;
-module_param(deemphasis_50, int, 0644);
-MODULE_PARM_DESC(deemphasis_50, "0 - 75us deemphasis; 1 - 50us deemphasis");
-
-/* ---------------------------------------------------------------------- */
-
-struct tda8290_priv {
-       struct tuner_i2c_props i2c_props;
-
-       unsigned char tda8290_easy_mode;
-
-       unsigned char tda827x_addr;
-
-       unsigned char ver;
-#define TDA8290   1
-#define TDA8295   2
-#define TDA8275   4
-#define TDA8275A  8
-#define TDA18271 16
-
-       struct tda827x_config cfg;
-};
-
-/*---------------------------------------------------------------------*/
-
-static int tda8290_i2c_bridge(struct dvb_frontend *fe, int close)
-{
-       struct tda8290_priv *priv = fe->analog_demod_priv;
-
-       unsigned char  enable[2] = { 0x21, 0xC0 };
-       unsigned char disable[2] = { 0x21, 0x00 };
-       unsigned char *msg;
-
-       if (close) {
-               msg = enable;
-               tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
-               /* let the bridge stabilize */
-               msleep(20);
-       } else {
-               msg = disable;
-               tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
-       }
-
-       return 0;
-}
-
-static int tda8295_i2c_bridge(struct dvb_frontend *fe, int close)
-{
-       struct tda8290_priv *priv = fe->analog_demod_priv;
-
-       unsigned char  enable[2] = { 0x45, 0xc1 };
-       unsigned char disable[2] = { 0x46, 0x00 };
-       unsigned char buf[3] = { 0x45, 0x01, 0x00 };
-       unsigned char *msg;
-
-       if (close) {
-               msg = enable;
-               tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
-               /* let the bridge stabilize */
-               msleep(20);
-       } else {
-               msg = disable;
-               tuner_i2c_xfer_send_recv(&priv->i2c_props, msg, 1, &msg[1], 1);
-
-               buf[2] = msg[1];
-               buf[2] &= ~0x04;
-               tuner_i2c_xfer_send(&priv->i2c_props, buf, 3);
-               msleep(5);
-
-               msg[1] |= 0x04;
-               tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
-       }
-
-       return 0;
-}
-
-/*---------------------------------------------------------------------*/
-
-static void set_audio(struct dvb_frontend *fe,
-                     struct analog_parameters *params)
-{
-       struct tda8290_priv *priv = fe->analog_demod_priv;
-       char* mode;
-
-       if (params->std & V4L2_STD_MN) {
-               priv->tda8290_easy_mode = 0x01;
-               mode = "MN";
-       } else if (params->std & V4L2_STD_B) {
-               priv->tda8290_easy_mode = 0x02;
-               mode = "B";
-       } else if (params->std & V4L2_STD_GH) {
-               priv->tda8290_easy_mode = 0x04;
-               mode = "GH";
-       } else if (params->std & V4L2_STD_PAL_I) {
-               priv->tda8290_easy_mode = 0x08;
-               mode = "I";
-       } else if (params->std & V4L2_STD_DK) {
-               priv->tda8290_easy_mode = 0x10;
-               mode = "DK";
-       } else if (params->std & V4L2_STD_SECAM_L) {
-               priv->tda8290_easy_mode = 0x20;
-               mode = "L";
-       } else if (params->std & V4L2_STD_SECAM_LC) {
-               priv->tda8290_easy_mode = 0x40;
-               mode = "LC";
-       } else {
-               priv->tda8290_easy_mode = 0x10;
-               mode = "xx";
-       }
-
-       if (params->mode == V4L2_TUNER_RADIO) {
-               /* Set TDA8295 to FM radio; Start TDA8290 with MN values */
-               priv->tda8290_easy_mode = (priv->ver & TDA8295) ? 0x80 : 0x01;
-               tuner_dbg("setting to radio FM\n");
-       } else {
-               tuner_dbg("setting tda829x to system %s\n", mode);
-       }
-}
-
-static struct {
-       unsigned char seq[2];
-} fm_mode[] = {
-       { { 0x01, 0x81} },      /* Put device into expert mode */
-       { { 0x03, 0x48} },      /* Disable NOTCH and VIDEO filters */
-       { { 0x04, 0x04} },      /* Disable color carrier filter (SSIF) */
-       { { 0x05, 0x04} },      /* ADC headroom */
-       { { 0x06, 0x10} },      /* group delay flat */
-
-       { { 0x07, 0x00} },      /* use the same radio DTO values as a tda8295 */
-       { { 0x08, 0x00} },
-       { { 0x09, 0x80} },
-       { { 0x0a, 0xda} },
-       { { 0x0b, 0x4b} },
-       { { 0x0c, 0x68} },
-
-       { { 0x0d, 0x00} },      /* PLL off, no video carrier detect */
-       { { 0x14, 0x00} },      /* disable auto mute if no video */
-};
-
-static void tda8290_set_params(struct dvb_frontend *fe,
-                              struct analog_parameters *params)
-{
-       struct tda8290_priv *priv = fe->analog_demod_priv;
-
-       unsigned char soft_reset[]  = { 0x00, 0x00 };
-       unsigned char easy_mode[]   = { 0x01, priv->tda8290_easy_mode };
-       unsigned char expert_mode[] = { 0x01, 0x80 };
-       unsigned char agc_out_on[]  = { 0x02, 0x00 };
-       unsigned char gainset_off[] = { 0x28, 0x14 };
-       unsigned char if_agc_spd[]  = { 0x0f, 0x88 };
-       unsigned char adc_head_6[]  = { 0x05, 0x04 };
-       unsigned char adc_head_9[]  = { 0x05, 0x02 };
-       unsigned char adc_head_12[] = { 0x05, 0x01 };
-       unsigned char pll_bw_nom[]  = { 0x0d, 0x47 };
-       unsigned char pll_bw_low[]  = { 0x0d, 0x27 };
-       unsigned char gainset_2[]   = { 0x28, 0x64 };
-       unsigned char agc_rst_on[]  = { 0x0e, 0x0b };
-       unsigned char agc_rst_off[] = { 0x0e, 0x09 };
-       unsigned char if_agc_set[]  = { 0x0f, 0x81 };
-       unsigned char addr_adc_sat  = 0x1a;
-       unsigned char addr_agc_stat = 0x1d;
-       unsigned char addr_pll_stat = 0x1b;
-       unsigned char adc_sat, agc_stat,
-                     pll_stat;
-       int i;
-
-       set_audio(fe, params);
-
-       if (priv->cfg.config)
-               tuner_dbg("tda827xa config is 0x%02x\n", priv->cfg.config);
-       tuner_i2c_xfer_send(&priv->i2c_props, easy_mode, 2);
-       tuner_i2c_xfer_send(&priv->i2c_props, agc_out_on, 2);
-       tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2);
-       msleep(1);
-
-       if (params->mode == V4L2_TUNER_RADIO) {
-               unsigned char deemphasis[]  = { 0x13, 1 };
-
-               /* FIXME: allow using a different deemphasis */
-
-               if (deemphasis_50)
-                       deemphasis[1] = 2;
-
-               for (i = 0; i < ARRAY_SIZE(fm_mode); i++)
-                       tuner_i2c_xfer_send(&priv->i2c_props, fm_mode[i].seq, 2);
-
-               tuner_i2c_xfer_send(&priv->i2c_props, deemphasis, 2);
-       } else {
-               expert_mode[1] = priv->tda8290_easy_mode + 0x80;
-               tuner_i2c_xfer_send(&priv->i2c_props, expert_mode, 2);
-               tuner_i2c_xfer_send(&priv->i2c_props, gainset_off, 2);
-               tuner_i2c_xfer_send(&priv->i2c_props, if_agc_spd, 2);
-               if (priv->tda8290_easy_mode & 0x60)
-                       tuner_i2c_xfer_send(&priv->i2c_props, adc_head_9, 2);
-               else
-                       tuner_i2c_xfer_send(&priv->i2c_props, adc_head_6, 2);
-               tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2);
-       }
-
-
-       tda8290_i2c_bridge(fe, 1);
-
-       if (fe->ops.tuner_ops.set_analog_params)
-               fe->ops.tuner_ops.set_analog_params(fe, params);
-
-       for (i = 0; i < 3; i++) {
-               tuner_i2c_xfer_send_recv(&priv->i2c_props,
-                                        &addr_pll_stat, 1, &pll_stat, 1);
-               if (pll_stat & 0x80) {
-                       tuner_i2c_xfer_send_recv(&priv->i2c_props,
-                                                &addr_adc_sat, 1,
-                                                &adc_sat, 1);
-                       tuner_i2c_xfer_send_recv(&priv->i2c_props,
-                                                &addr_agc_stat, 1,
-                                                &agc_stat, 1);
-                       tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat);
-                       break;
-               } else {
-                       tuner_dbg("tda8290 not locked, no signal?\n");
-                       msleep(100);
-               }
-       }
-       /* adjust headroom resp. gain */
-       if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) {
-               tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n",
-                          agc_stat, adc_sat, pll_stat & 0x80);
-               tuner_i2c_xfer_send(&priv->i2c_props, gainset_2, 2);
-               msleep(100);
-               tuner_i2c_xfer_send_recv(&priv->i2c_props,
-                                        &addr_agc_stat, 1, &agc_stat, 1);
-               tuner_i2c_xfer_send_recv(&priv->i2c_props,
-                                        &addr_pll_stat, 1, &pll_stat, 1);
-               if ((agc_stat > 115) || !(pll_stat & 0x80)) {
-                       tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n",
-                                  agc_stat, pll_stat & 0x80);
-                       if (priv->cfg.agcf)
-                               priv->cfg.agcf(fe);
-                       msleep(100);
-                       tuner_i2c_xfer_send_recv(&priv->i2c_props,
-                                                &addr_agc_stat, 1,
-                                                &agc_stat, 1);
-                       tuner_i2c_xfer_send_recv(&priv->i2c_props,
-                                                &addr_pll_stat, 1,
-                                                &pll_stat, 1);
-                       if((agc_stat > 115) || !(pll_stat & 0x80)) {
-                               tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat);
-                               tuner_i2c_xfer_send(&priv->i2c_props, adc_head_12, 2);
-                               tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_low, 2);
-                               msleep(100);
-                       }
-               }
-       }
-
-       /* l/ l' deadlock? */
-       if(priv->tda8290_easy_mode & 0x60) {
-               tuner_i2c_xfer_send_recv(&priv->i2c_props,
-                                        &addr_adc_sat, 1,
-                                        &adc_sat, 1);
-               tuner_i2c_xfer_send_recv(&priv->i2c_props,
-                                        &addr_pll_stat, 1,
-                                        &pll_stat, 1);
-               if ((adc_sat > 20) || !(pll_stat & 0x80)) {
-                       tuner_dbg("trying to resolve SECAM L deadlock\n");
-                       tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_on, 2);
-                       msleep(40);
-                       tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_off, 2);
-               }
-       }
-
-       tda8290_i2c_bridge(fe, 0);
-       tuner_i2c_xfer_send(&priv->i2c_props, if_agc_set, 2);
-}
-
-/*---------------------------------------------------------------------*/
-
-static void tda8295_power(struct dvb_frontend *fe, int enable)
-{
-       struct tda8290_priv *priv = fe->analog_demod_priv;
-       unsigned char buf[] = { 0x30, 0x00 }; /* clb_stdbt */
-
-       tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1);
-
-       if (enable)
-               buf[1] = 0x01;
-       else
-               buf[1] = 0x03;
-
-       tuner_i2c_xfer_send(&priv->i2c_props, buf, 2);
-}
-
-static void tda8295_set_easy_mode(struct dvb_frontend *fe, int enable)
-{
-       struct tda8290_priv *priv = fe->analog_demod_priv;
-       unsigned char buf[] = { 0x01, 0x00 };
-
-       tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1);
-
-       if (enable)
-               buf[1] = 0x01; /* rising edge sets regs 0x02 - 0x23 */
-       else
-               buf[1] = 0x00; /* reset active bit */
-
-       tuner_i2c_xfer_send(&priv->i2c_props, buf, 2);
-}
-
-static void tda8295_set_video_std(struct dvb_frontend *fe)
-{
-       struct tda8290_priv *priv = fe->analog_demod_priv;
-       unsigned char buf[] = { 0x00, priv->tda8290_easy_mode };
-
-       tuner_i2c_xfer_send(&priv->i2c_props, buf, 2);
-
-       tda8295_set_easy_mode(fe, 1);
-       msleep(20);
-       tda8295_set_easy_mode(fe, 0);
-}
-
-/*---------------------------------------------------------------------*/
-
-static void tda8295_agc1_out(struct dvb_frontend *fe, int enable)
-{
-       struct tda8290_priv *priv = fe->analog_demod_priv;
-       unsigned char buf[] = { 0x02, 0x00 }; /* DIV_FUNC */
-
-       tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1);
-
-       if (enable)
-               buf[1] &= ~0x40;
-       else
-               buf[1] |= 0x40;
-
-       tuner_i2c_xfer_send(&priv->i2c_props, buf, 2);
-}
-
-static void tda8295_agc2_out(struct dvb_frontend *fe, int enable)
-{
-       struct tda8290_priv *priv = fe->analog_demod_priv;
-       unsigned char set_gpio_cf[]    = { 0x44, 0x00 };
-       unsigned char set_gpio_val[]   = { 0x46, 0x00 };
-
-       tuner_i2c_xfer_send_recv(&priv->i2c_props,
-                                &set_gpio_cf[0], 1, &set_gpio_cf[1], 1);
-       tuner_i2c_xfer_send_recv(&priv->i2c_props,
-                                &set_gpio_val[0], 1, &set_gpio_val[1], 1);
-
-       set_gpio_cf[1] &= 0xf0; /* clear GPIO_0 bits 3-0 */
-
-       if (enable) {
-               set_gpio_cf[1]  |= 0x01; /* config GPIO_0 as Open Drain Out */
-               set_gpio_val[1] &= 0xfe; /* set GPIO_0 pin low */
-       }
-       tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_cf, 2);
-       tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_val, 2);
-}
-
-static int tda8295_has_signal(struct dvb_frontend *fe)
-{
-       struct tda8290_priv *priv = fe->analog_demod_priv;
-
-       unsigned char hvpll_stat = 0x26;
-       unsigned char ret;
-
-       tuner_i2c_xfer_send_recv(&priv->i2c_props, &hvpll_stat, 1, &ret, 1);
-       return (ret & 0x01) ? 65535 : 0;
-}
-
-/*---------------------------------------------------------------------*/
-
-static void tda8295_set_params(struct dvb_frontend *fe,
-                              struct analog_parameters *params)
-{
-       struct tda8290_priv *priv = fe->analog_demod_priv;
-
-       unsigned char blanking_mode[]     = { 0x1d, 0x00 };
-
-       set_audio(fe, params);
-
-       tuner_dbg("%s: freq = %d\n", __func__, params->frequency);
-
-       tda8295_power(fe, 1);
-       tda8295_agc1_out(fe, 1);
-
-       tuner_i2c_xfer_send_recv(&priv->i2c_props,
-                                &blanking_mode[0], 1, &blanking_mode[1], 1);
-
-       tda8295_set_video_std(fe);
-
-       blanking_mode[1] = 0x03;
-       tuner_i2c_xfer_send(&priv->i2c_props, blanking_mode, 2);
-       msleep(20);
-
-       tda8295_i2c_bridge(fe, 1);
-
-       if (fe->ops.tuner_ops.set_analog_params)
-               fe->ops.tuner_ops.set_analog_params(fe, params);
-
-       if (priv->cfg.agcf)
-               priv->cfg.agcf(fe);
-
-       if (tda8295_has_signal(fe))
-               tuner_dbg("tda8295 is locked\n");
-       else
-               tuner_dbg("tda8295 not locked, no signal?\n");
-
-       tda8295_i2c_bridge(fe, 0);
-}
-
-/*---------------------------------------------------------------------*/
-
-static int tda8290_has_signal(struct dvb_frontend *fe)
-{
-       struct tda8290_priv *priv = fe->analog_demod_priv;
-
-       unsigned char i2c_get_afc[1] = { 0x1B };
-       unsigned char afc = 0;
-
-       tuner_i2c_xfer_send_recv(&priv->i2c_props,
-                                i2c_get_afc, ARRAY_SIZE(i2c_get_afc), &afc, 1);
-       return (afc & 0x80)? 65535:0;
-}
-
-/*---------------------------------------------------------------------*/
-
-static void tda8290_standby(struct dvb_frontend *fe)
-{
-       struct tda8290_priv *priv = fe->analog_demod_priv;
-
-       unsigned char cb1[] = { 0x30, 0xD0 };
-       unsigned char tda8290_standby[] = { 0x00, 0x02 };
-       unsigned char tda8290_agc_tri[] = { 0x02, 0x20 };
-       struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, .buf=cb1, .len = 2};
-
-       tda8290_i2c_bridge(fe, 1);
-       if (priv->ver & TDA8275A)
-               cb1[1] = 0x90;
-       i2c_transfer(priv->i2c_props.adap, &msg, 1);
-       tda8290_i2c_bridge(fe, 0);
-       tuner_i2c_xfer_send(&priv->i2c_props, tda8290_agc_tri, 2);
-       tuner_i2c_xfer_send(&priv->i2c_props, tda8290_standby, 2);
-}
-
-static void tda8295_standby(struct dvb_frontend *fe)
-{
-       tda8295_agc1_out(fe, 0); /* Put AGC in tri-state */
-
-       tda8295_power(fe, 0);
-}
-
-static void tda8290_init_if(struct dvb_frontend *fe)
-{
-       struct tda8290_priv *priv = fe->analog_demod_priv;
-
-       unsigned char set_VS[] = { 0x30, 0x6F };
-       unsigned char set_GP00_CF[] = { 0x20, 0x01 };
-       unsigned char set_GP01_CF[] = { 0x20, 0x0B };
-
-       if ((priv->cfg.config == 1) || (priv->cfg.config == 2))
-               tuner_i2c_xfer_send(&priv->i2c_props, set_GP00_CF, 2);
-       else
-               tuner_i2c_xfer_send(&priv->i2c_props, set_GP01_CF, 2);
-       tuner_i2c_xfer_send(&priv->i2c_props, set_VS, 2);
-}
-
-static void tda8295_init_if(struct dvb_frontend *fe)
-{
-       struct tda8290_priv *priv = fe->analog_demod_priv;
-
-       static unsigned char set_adc_ctl[]       = { 0x33, 0x14 };
-       static unsigned char set_adc_ctl2[]      = { 0x34, 0x00 };
-       static unsigned char set_pll_reg6[]      = { 0x3e, 0x63 };
-       static unsigned char set_pll_reg0[]      = { 0x38, 0x23 };
-       static unsigned char set_pll_reg7[]      = { 0x3f, 0x01 };
-       static unsigned char set_pll_reg10[]     = { 0x42, 0x61 };
-       static unsigned char set_gpio_reg0[]     = { 0x44, 0x0b };
-
-       tda8295_power(fe, 1);
-
-       tda8295_set_easy_mode(fe, 0);
-       tda8295_set_video_std(fe);
-
-       tuner_i2c_xfer_send(&priv->i2c_props, set_adc_ctl, 2);
-       tuner_i2c_xfer_send(&priv->i2c_props, set_adc_ctl2, 2);
-       tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg6, 2);
-       tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg0, 2);
-       tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg7, 2);
-       tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg10, 2);
-       tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_reg0, 2);
-
-       tda8295_agc1_out(fe, 0);
-       tda8295_agc2_out(fe, 0);
-}
-
-static void tda8290_init_tuner(struct dvb_frontend *fe)
-{
-       struct tda8290_priv *priv = fe->analog_demod_priv;
-       unsigned char tda8275_init[]  = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf,
-                                         0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 };
-       unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b,
-                                         0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b };
-       struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0,
-                             .buf=tda8275_init, .len = 14};
-       if (priv->ver & TDA8275A)
-               msg.buf = tda8275a_init;
-
-       tda8290_i2c_bridge(fe, 1);
-       i2c_transfer(priv->i2c_props.adap, &msg, 1);
-       tda8290_i2c_bridge(fe, 0);
-}
-
-/*---------------------------------------------------------------------*/
-
-static void tda829x_release(struct dvb_frontend *fe)
-{
-       struct tda8290_priv *priv = fe->analog_demod_priv;
-
-       /* only try to release the tuner if we've
-        * attached it from within this module */
-       if (priv->ver & (TDA18271 | TDA8275 | TDA8275A))
-               if (fe->ops.tuner_ops.release)
-                       fe->ops.tuner_ops.release(fe);
-
-       kfree(fe->analog_demod_priv);
-       fe->analog_demod_priv = NULL;
-}
-
-static struct tda18271_config tda829x_tda18271_config = {
-       .gate    = TDA18271_GATE_ANALOG,
-};
-
-static int tda829x_find_tuner(struct dvb_frontend *fe)
-{
-       struct tda8290_priv *priv = fe->analog_demod_priv;
-       struct analog_demod_ops *analog_ops = &fe->ops.analog_ops;
-       int i, ret, tuners_found;
-       u32 tuner_addrs;
-       u8 data;
-       struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 };
-
-       if (!analog_ops->i2c_gate_ctrl) {
-               printk(KERN_ERR "tda8290: no gate control were provided!\n");
-
-               return -EINVAL;
-       }
-
-       analog_ops->i2c_gate_ctrl(fe, 1);
-
-       /* probe for tuner chip */
-       tuners_found = 0;
-       tuner_addrs = 0;
-       for (i = 0x60; i <= 0x63; i++) {
-               msg.addr = i;
-               ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
-               if (ret == 1) {
-                       tuners_found++;
-                       tuner_addrs = (tuner_addrs << 8) + i;
-               }
-       }
-       /* if there is more than one tuner, we expect the right one is
-          behind the bridge and we choose the highest address that doesn't
-          give a response now
-        */
-
-       analog_ops->i2c_gate_ctrl(fe, 0);
-
-       if (tuners_found > 1)
-               for (i = 0; i < tuners_found; i++) {
-                       msg.addr = tuner_addrs  & 0xff;
-                       ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
-                       if (ret == 1)
-                               tuner_addrs = tuner_addrs >> 8;
-                       else
-                               break;
-               }
-
-       if (tuner_addrs == 0) {
-               tuner_addrs = 0x60;
-               tuner_info("could not clearly identify tuner address, "
-                          "defaulting to %x\n", tuner_addrs);
-       } else {
-               tuner_addrs = tuner_addrs & 0xff;
-               tuner_info("setting tuner address to %x\n", tuner_addrs);
-       }
-       priv->tda827x_addr = tuner_addrs;
-       msg.addr = tuner_addrs;
-
-       analog_ops->i2c_gate_ctrl(fe, 1);
-       ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
-
-       if (ret != 1) {
-               tuner_warn("tuner access failed!\n");
-               analog_ops->i2c_gate_ctrl(fe, 0);
-               return -EREMOTEIO;
-       }
-
-       if ((data == 0x83) || (data == 0x84)) {
-               priv->ver |= TDA18271;
-               tda829x_tda18271_config.config = priv->cfg.config;
-               dvb_attach(tda18271_attach, fe, priv->tda827x_addr,
-                          priv->i2c_props.adap, &tda829x_tda18271_config);
-       } else {
-               if ((data & 0x3c) == 0)
-                       priv->ver |= TDA8275;
-               else
-                       priv->ver |= TDA8275A;
-
-               dvb_attach(tda827x_attach, fe, priv->tda827x_addr,
-                          priv->i2c_props.adap, &priv->cfg);
-               priv->cfg.switch_addr = priv->i2c_props.addr;
-       }
-       if (fe->ops.tuner_ops.init)
-               fe->ops.tuner_ops.init(fe);
-
-       if (fe->ops.tuner_ops.sleep)
-               fe->ops.tuner_ops.sleep(fe);
-
-       analog_ops->i2c_gate_ctrl(fe, 0);
-
-       return 0;
-}
-
-static int tda8290_probe(struct tuner_i2c_props *i2c_props)
-{
-#define TDA8290_ID 0x89
-       u8 reg = 0x1f, id;
-       struct i2c_msg msg_read[] = {
-               { .addr = i2c_props->addr, .flags = 0, .len = 1, .buf = &reg },
-               { .addr = i2c_props->addr, .flags = I2C_M_RD, .len = 1, .buf = &id },
-       };
-
-       /* detect tda8290 */
-       if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) {
-               printk(KERN_WARNING "%s: couldn't read register 0x%02x\n",
-                              __func__, reg);
-               return -ENODEV;
-       }
-
-       if (id == TDA8290_ID) {
-               if (debug)
-                       printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n",
-                              __func__, i2c_adapter_id(i2c_props->adap),
-                              i2c_props->addr);
-               return 0;
-       }
-       return -ENODEV;
-}
-
-static int tda8295_probe(struct tuner_i2c_props *i2c_props)
-{
-#define TDA8295_ID 0x8a
-#define TDA8295C2_ID 0x8b
-       u8 reg = 0x2f, id;
-       struct i2c_msg msg_read[] = {
-               { .addr = i2c_props->addr, .flags = 0, .len = 1, .buf = &reg },
-               { .addr = i2c_props->addr, .flags = I2C_M_RD, .len = 1, .buf = &id },
-       };
-
-       /* detect tda8295 */
-       if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) {
-               printk(KERN_WARNING "%s: couldn't read register 0x%02x\n",
-                              __func__, reg);
-               return -ENODEV;
-       }
-
-       if ((id & 0xfe) == TDA8295_ID) {
-               if (debug)
-                       printk(KERN_DEBUG "%s: %s detected @ %d-%04x\n",
-                              __func__, (id == TDA8295_ID) ?
-                              "tda8295c1" : "tda8295c2",
-                              i2c_adapter_id(i2c_props->adap),
-                              i2c_props->addr);
-               return 0;
-       }
-
-       return -ENODEV;
-}
-
-static struct analog_demod_ops tda8290_ops = {
-       .set_params     = tda8290_set_params,
-       .has_signal     = tda8290_has_signal,
-       .standby        = tda8290_standby,
-       .release        = tda829x_release,
-       .i2c_gate_ctrl  = tda8290_i2c_bridge,
-};
-
-static struct analog_demod_ops tda8295_ops = {
-       .set_params     = tda8295_set_params,
-       .has_signal     = tda8295_has_signal,
-       .standby        = tda8295_standby,
-       .release        = tda829x_release,
-       .i2c_gate_ctrl  = tda8295_i2c_bridge,
-};
-
-struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
-                                   struct i2c_adapter *i2c_adap, u8 i2c_addr,
-                                   struct tda829x_config *cfg)
-{
-       struct tda8290_priv *priv = NULL;
-       char *name;
-
-       priv = kzalloc(sizeof(struct tda8290_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-       fe->analog_demod_priv = priv;
-
-       priv->i2c_props.addr     = i2c_addr;
-       priv->i2c_props.adap     = i2c_adap;
-       priv->i2c_props.name     = "tda829x";
-       if (cfg)
-               priv->cfg.config         = cfg->lna_cfg;
-
-       if (tda8290_probe(&priv->i2c_props) == 0) {
-               priv->ver = TDA8290;
-               memcpy(&fe->ops.analog_ops, &tda8290_ops,
-                      sizeof(struct analog_demod_ops));
-       }
-
-       if (tda8295_probe(&priv->i2c_props) == 0) {
-               priv->ver = TDA8295;
-               memcpy(&fe->ops.analog_ops, &tda8295_ops,
-                      sizeof(struct analog_demod_ops));
-       }
-
-       if (!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) {
-               tda8295_power(fe, 1);
-               if (tda829x_find_tuner(fe) < 0)
-                       goto fail;
-       }
-
-       switch (priv->ver) {
-       case TDA8290:
-               name = "tda8290";
-               break;
-       case TDA8295:
-               name = "tda8295";
-               break;
-       case TDA8290 | TDA8275:
-               name = "tda8290+75";
-               break;
-       case TDA8295 | TDA8275:
-               name = "tda8295+75";
-               break;
-       case TDA8290 | TDA8275A:
-               name = "tda8290+75a";
-               break;
-       case TDA8295 | TDA8275A:
-               name = "tda8295+75a";
-               break;
-       case TDA8290 | TDA18271:
-               name = "tda8290+18271";
-               break;
-       case TDA8295 | TDA18271:
-               name = "tda8295+18271";
-               break;
-       default:
-               goto fail;
-       }
-       tuner_info("type set to %s\n", name);
-
-       fe->ops.analog_ops.info.name = name;
-
-       if (priv->ver & TDA8290) {
-               if (priv->ver & (TDA8275 | TDA8275A))
-                       tda8290_init_tuner(fe);
-               tda8290_init_if(fe);
-       } else if (priv->ver & TDA8295)
-               tda8295_init_if(fe);
-
-       return fe;
-
-fail:
-       memset(&fe->ops.analog_ops, 0, sizeof(struct analog_demod_ops));
-
-       tda829x_release(fe);
-       return NULL;
-}
-EXPORT_SYMBOL_GPL(tda829x_attach);
-
-int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr)
-{
-       struct tuner_i2c_props i2c_props = {
-               .adap = i2c_adap,
-               .addr = i2c_addr,
-       };
-
-       unsigned char soft_reset[]   = { 0x00, 0x00 };
-       unsigned char easy_mode_b[]  = { 0x01, 0x02 };
-       unsigned char easy_mode_g[]  = { 0x01, 0x04 };
-       unsigned char restore_9886[] = { 0x00, 0xd6, 0x30 };
-       unsigned char addr_dto_lsb = 0x07;
-       unsigned char data;
-#define PROBE_BUFFER_SIZE 8
-       unsigned char buf[PROBE_BUFFER_SIZE];
-       int i;
-
-       /* rule out tda9887, which would return the same byte repeatedly */
-       tuner_i2c_xfer_send_recv(&i2c_props,
-                                soft_reset, 1, buf, PROBE_BUFFER_SIZE);
-       for (i = 1; i < PROBE_BUFFER_SIZE; i++) {
-               if (buf[i] != buf[0])
-                       break;
-       }
-
-       /* all bytes are equal, not a tda829x - probably a tda9887 */
-       if (i == PROBE_BUFFER_SIZE)
-               return -ENODEV;
-
-       if ((tda8290_probe(&i2c_props) == 0) ||
-           (tda8295_probe(&i2c_props) == 0))
-               return 0;
-
-       /* fall back to old probing method */
-       tuner_i2c_xfer_send(&i2c_props, easy_mode_b, 2);
-       tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
-       tuner_i2c_xfer_send_recv(&i2c_props, &addr_dto_lsb, 1, &data, 1);
-       if (data == 0) {
-               tuner_i2c_xfer_send(&i2c_props, easy_mode_g, 2);
-               tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
-               tuner_i2c_xfer_send_recv(&i2c_props,
-                                        &addr_dto_lsb, 1, &data, 1);
-               if (data == 0x7b) {
-                       return 0;
-               }
-       }
-       tuner_i2c_xfer_send(&i2c_props, restore_9886, 3);
-       return -ENODEV;
-}
-EXPORT_SYMBOL_GPL(tda829x_probe);
-
-MODULE_DESCRIPTION("Philips/NXP TDA8290/TDA8295 analog IF demodulator driver");
-MODULE_AUTHOR("Gerd Knorr, Hartmut Hackmann, Michael Krufky");
-MODULE_LICENSE("GPL");
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/common/tuners/tda8290.h b/drivers/media/common/tuners/tda8290.h
deleted file mode 100644 (file)
index 7e288b2..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-    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 __TDA8290_H__
-#define __TDA8290_H__
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-
-struct tda829x_config {
-       unsigned int lna_cfg;
-
-       unsigned int probe_tuner:1;
-#define TDA829X_PROBE_TUNER 0
-#define TDA829X_DONT_PROBE  1
-};
-
-#if defined(CONFIG_MEDIA_TUNER_TDA8290) || (defined(CONFIG_MEDIA_TUNER_TDA8290_MODULE) && defined(MODULE))
-extern int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr);
-
-extern struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
-                                          struct i2c_adapter *i2c_adap,
-                                          u8 i2c_addr,
-                                          struct tda829x_config *cfg);
-#else
-static inline int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return -EINVAL;
-}
-
-static inline struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
-                                                 struct i2c_adapter *i2c_adap,
-                                                 u8 i2c_addr,
-                                                 struct tda829x_config *cfg)
-{
-       printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
-              __func__);
-       return NULL;
-}
-#endif
-
-#endif /* __TDA8290_H__ */
diff --git a/drivers/media/common/tuners/tda9887.c b/drivers/media/common/tuners/tda9887.c
deleted file mode 100644 (file)
index cdb645d..0000000
+++ /dev/null
@@ -1,717 +0,0 @@
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/i2c.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/tuner.h>
-#include "tuner-i2c.h"
-#include "tda9887.h"
-
-
-/* Chips:
-   TDA9885 (PAL, NTSC)
-   TDA9886 (PAL, SECAM, NTSC)
-   TDA9887 (PAL, SECAM, NTSC, FM Radio)
-
-   Used as part of several tuners
-*/
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable verbose debug messages");
-
-static DEFINE_MUTEX(tda9887_list_mutex);
-static LIST_HEAD(hybrid_tuner_instance_list);
-
-struct tda9887_priv {
-       struct tuner_i2c_props i2c_props;
-       struct list_head hybrid_tuner_instance_list;
-
-       unsigned char      data[4];
-       unsigned int       config;
-       unsigned int       mode;
-       unsigned int       audmode;
-       v4l2_std_id        std;
-
-       bool               standby;
-};
-
-/* ---------------------------------------------------------------------- */
-
-#define UNSET       (-1U)
-
-struct tvnorm {
-       v4l2_std_id       std;
-       char              *name;
-       unsigned char     b;
-       unsigned char     c;
-       unsigned char     e;
-};
-
-/* ---------------------------------------------------------------------- */
-
-//
-// TDA defines
-//
-
-//// first reg (b)
-#define cVideoTrapBypassOFF     0x00    // bit b0
-#define cVideoTrapBypassON      0x01    // bit b0
-
-#define cAutoMuteFmInactive     0x00    // bit b1
-#define cAutoMuteFmActive       0x02    // bit b1
-
-#define cIntercarrier           0x00    // bit b2
-#define cQSS                    0x04    // bit b2
-
-#define cPositiveAmTV           0x00    // bit b3:4
-#define cFmRadio                0x08    // bit b3:4
-#define cNegativeFmTV           0x10    // bit b3:4
-
-
-#define cForcedMuteAudioON      0x20    // bit b5
-#define cForcedMuteAudioOFF     0x00    // bit b5
-
-#define cOutputPort1Active      0x00    // bit b6
-#define cOutputPort1Inactive    0x40    // bit b6
-
-#define cOutputPort2Active      0x00    // bit b7
-#define cOutputPort2Inactive    0x80    // bit b7
-
-
-//// second reg (c)
-#define cDeemphasisOFF          0x00    // bit c5
-#define cDeemphasisON           0x20    // bit c5
-
-#define cDeemphasis75           0x00    // bit c6
-#define cDeemphasis50           0x40    // bit c6
-
-#define cAudioGain0             0x00    // bit c7
-#define cAudioGain6             0x80    // bit c7
-
-#define cTopMask                0x1f    // bit c0:4
-#define cTopDefault            0x10    // bit c0:4
-
-//// third reg (e)
-#define cAudioIF_4_5             0x00    // bit e0:1
-#define cAudioIF_5_5             0x01    // bit e0:1
-#define cAudioIF_6_0             0x02    // bit e0:1
-#define cAudioIF_6_5             0x03    // bit e0:1
-
-
-#define cVideoIFMask           0x1c    // bit e2:4
-/* Video IF selection in TV Mode (bit B3=0) */
-#define cVideoIF_58_75           0x00    // bit e2:4
-#define cVideoIF_45_75           0x04    // bit e2:4
-#define cVideoIF_38_90           0x08    // bit e2:4
-#define cVideoIF_38_00           0x0C    // bit e2:4
-#define cVideoIF_33_90           0x10    // bit e2:4
-#define cVideoIF_33_40           0x14    // bit e2:4
-#define cRadioIF_45_75           0x18    // bit e2:4
-#define cRadioIF_38_90           0x1C    // bit e2:4
-
-/* IF1 selection in Radio Mode (bit B3=1) */
-#define cRadioIF_33_30         0x00    // bit e2,4 (also 0x10,0x14)
-#define cRadioIF_41_30         0x04    // bit e2,4
-
-/* Output of AFC pin in radio mode when bit E7=1 */
-#define cRadioAGC_SIF          0x00    // bit e3
-#define cRadioAGC_FM           0x08    // bit e3
-
-#define cTunerGainNormal         0x00    // bit e5
-#define cTunerGainLow            0x20    // bit e5
-
-#define cGating_18               0x00    // bit e6
-#define cGating_36               0x40    // bit e6
-
-#define cAgcOutON                0x80    // bit e7
-#define cAgcOutOFF               0x00    // bit e7
-
-/* ---------------------------------------------------------------------- */
-
-static struct tvnorm tvnorms[] = {
-       {
-               .std   = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N,
-               .name  = "PAL-BGHN",
-               .b     = ( cNegativeFmTV  |
-                          cQSS           ),
-               .c     = ( cDeemphasisON  |
-                          cDeemphasis50  |
-                          cTopDefault),
-               .e     = ( cGating_36     |
-                          cAudioIF_5_5   |
-                          cVideoIF_38_90 ),
-       },{
-               .std   = V4L2_STD_PAL_I,
-               .name  = "PAL-I",
-               .b     = ( cNegativeFmTV  |
-                          cQSS           ),
-               .c     = ( cDeemphasisON  |
-                          cDeemphasis50  |
-                          cTopDefault),
-               .e     = ( cGating_36     |
-                          cAudioIF_6_0   |
-                          cVideoIF_38_90 ),
-       },{
-               .std   = V4L2_STD_PAL_DK,
-               .name  = "PAL-DK",
-               .b     = ( cNegativeFmTV  |
-                          cQSS           ),
-               .c     = ( cDeemphasisON  |
-                          cDeemphasis50  |
-                          cTopDefault),
-               .e     = ( cGating_36     |
-                          cAudioIF_6_5   |
-                          cVideoIF_38_90 ),
-       },{
-               .std   = V4L2_STD_PAL_M | V4L2_STD_PAL_Nc,
-               .name  = "PAL-M/Nc",
-               .b     = ( cNegativeFmTV  |
-                          cQSS           ),
-               .c     = ( cDeemphasisON  |
-                          cDeemphasis75  |
-                          cTopDefault),
-               .e     = ( cGating_36     |
-                          cAudioIF_4_5   |
-                          cVideoIF_45_75 ),
-       },{
-               .std   = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H,
-               .name  = "SECAM-BGH",
-               .b     = ( cNegativeFmTV  |
-                          cQSS           ),
-               .c     = ( cTopDefault),
-               .e     = ( cAudioIF_5_5   |
-                          cVideoIF_38_90 ),
-       },{
-               .std   = V4L2_STD_SECAM_L,
-               .name  = "SECAM-L",
-               .b     = ( cPositiveAmTV  |
-                          cQSS           ),
-               .c     = ( cTopDefault),
-               .e     = ( cGating_36     |
-                          cAudioIF_6_5   |
-                          cVideoIF_38_90 ),
-       },{
-               .std   = V4L2_STD_SECAM_LC,
-               .name  = "SECAM-L'",
-               .b     = ( cOutputPort2Inactive |
-                          cPositiveAmTV  |
-                          cQSS           ),
-               .c     = ( cTopDefault),
-               .e     = ( cGating_36     |
-                          cAudioIF_6_5   |
-                          cVideoIF_33_90 ),
-       },{
-               .std   = V4L2_STD_SECAM_DK,
-               .name  = "SECAM-DK",
-               .b     = ( cNegativeFmTV  |
-                          cQSS           ),
-               .c     = ( cDeemphasisON  |
-                          cDeemphasis50  |
-                          cTopDefault),
-               .e     = ( cGating_36     |
-                          cAudioIF_6_5   |
-                          cVideoIF_38_90 ),
-       },{
-               .std   = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
-               .name  = "NTSC-M",
-               .b     = ( cNegativeFmTV  |
-                          cQSS           ),
-               .c     = ( cDeemphasisON  |
-                          cDeemphasis75  |
-                          cTopDefault),
-               .e     = ( cGating_36     |
-                          cAudioIF_4_5   |
-                          cVideoIF_45_75 ),
-       },{
-               .std   = V4L2_STD_NTSC_M_JP,
-               .name  = "NTSC-M-JP",
-               .b     = ( cNegativeFmTV  |
-                          cQSS           ),
-               .c     = ( cDeemphasisON  |
-                          cDeemphasis50  |
-                          cTopDefault),
-               .e     = ( cGating_36     |
-                          cAudioIF_4_5   |
-                          cVideoIF_58_75 ),
-       }
-};
-
-static struct tvnorm radio_stereo = {
-       .name = "Radio Stereo",
-       .b    = ( cFmRadio       |
-                 cQSS           ),
-       .c    = ( cDeemphasisOFF |
-                 cAudioGain6    |
-                 cTopDefault),
-       .e    = ( cTunerGainLow  |
-                 cAudioIF_5_5   |
-                 cRadioIF_38_90 ),
-};
-
-static struct tvnorm radio_mono = {
-       .name = "Radio Mono",
-       .b    = ( cFmRadio       |
-                 cQSS           ),
-       .c    = ( cDeemphasisON  |
-                 cDeemphasis75  |
-                 cTopDefault),
-       .e    = ( cTunerGainLow  |
-                 cAudioIF_5_5   |
-                 cRadioIF_38_90 ),
-};
-
-/* ---------------------------------------------------------------------- */
-
-static void dump_read_message(struct dvb_frontend *fe, unsigned char *buf)
-{
-       struct tda9887_priv *priv = fe->analog_demod_priv;
-
-       static char *afc[16] = {
-               "- 12.5 kHz",
-               "- 37.5 kHz",
-               "- 62.5 kHz",
-               "- 87.5 kHz",
-               "-112.5 kHz",
-               "-137.5 kHz",
-               "-162.5 kHz",
-               "-187.5 kHz [min]",
-               "+187.5 kHz [max]",
-               "+162.5 kHz",
-               "+137.5 kHz",
-               "+112.5 kHz",
-               "+ 87.5 kHz",
-               "+ 62.5 kHz",
-               "+ 37.5 kHz",
-               "+ 12.5 kHz",
-       };
-       tuner_info("read: 0x%2x\n", buf[0]);
-       tuner_info("  after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no");
-       tuner_info("  afc            : %s\n", afc[(buf[0] >> 1) & 0x0f]);
-       tuner_info("  fmif level     : %s\n", (buf[0] & 0x20) ? "high" : "low");
-       tuner_info("  afc window     : %s\n", (buf[0] & 0x40) ? "in" : "out");
-       tuner_info("  vfi level      : %s\n", (buf[0] & 0x80) ? "high" : "low");
-}
-
-static void dump_write_message(struct dvb_frontend *fe, unsigned char *buf)
-{
-       struct tda9887_priv *priv = fe->analog_demod_priv;
-
-       static char *sound[4] = {
-               "AM/TV",
-               "FM/radio",
-               "FM/TV",
-               "FM/radio"
-       };
-       static char *adjust[32] = {
-               "-16", "-15", "-14", "-13", "-12", "-11", "-10", "-9",
-               "-8",  "-7",  "-6",  "-5",  "-4",  "-3",  "-2",  "-1",
-               "0",   "+1",  "+2",  "+3",  "+4",  "+5",  "+6",  "+7",
-               "+8",  "+9",  "+10", "+11", "+12", "+13", "+14", "+15"
-       };
-       static char *deemph[4] = {
-               "no", "no", "75", "50"
-       };
-       static char *carrier[4] = {
-               "4.5 MHz",
-               "5.5 MHz",
-               "6.0 MHz",
-               "6.5 MHz / AM"
-       };
-       static char *vif[8] = {
-               "58.75 MHz",
-               "45.75 MHz",
-               "38.9 MHz",
-               "38.0 MHz",
-               "33.9 MHz",
-               "33.4 MHz",
-               "45.75 MHz + pin13",
-               "38.9 MHz + pin13",
-       };
-       static char *rif[4] = {
-               "44 MHz",
-               "52 MHz",
-               "52 MHz",
-               "44 MHz",
-       };
-
-       tuner_info("write: byte B 0x%02x\n", buf[1]);
-       tuner_info("  B0   video mode      : %s\n",
-                  (buf[1] & 0x01) ? "video trap" : "sound trap");
-       tuner_info("  B1   auto mute fm    : %s\n",
-                  (buf[1] & 0x02) ? "yes" : "no");
-       tuner_info("  B2   carrier mode    : %s\n",
-                  (buf[1] & 0x04) ? "QSS" : "Intercarrier");
-       tuner_info("  B3-4 tv sound/radio  : %s\n",
-                  sound[(buf[1] & 0x18) >> 3]);
-       tuner_info("  B5   force mute audio: %s\n",
-                  (buf[1] & 0x20) ? "yes" : "no");
-       tuner_info("  B6   output port 1   : %s\n",
-                  (buf[1] & 0x40) ? "high (inactive)" : "low (active)");
-       tuner_info("  B7   output port 2   : %s\n",
-                  (buf[1] & 0x80) ? "high (inactive)" : "low (active)");
-
-       tuner_info("write: byte C 0x%02x\n", buf[2]);
-       tuner_info("  C0-4 top adjustment  : %s dB\n",
-                  adjust[buf[2] & 0x1f]);
-       tuner_info("  C5-6 de-emphasis     : %s\n",
-                  deemph[(buf[2] & 0x60) >> 5]);
-       tuner_info("  C7   audio gain      : %s\n",
-                  (buf[2] & 0x80) ? "-6" : "0");
-
-       tuner_info("write: byte E 0x%02x\n", buf[3]);
-       tuner_info("  E0-1 sound carrier   : %s\n",
-                  carrier[(buf[3] & 0x03)]);
-       tuner_info("  E6   l pll gating   : %s\n",
-                  (buf[3] & 0x40) ? "36" : "13");
-
-       if (buf[1] & 0x08) {
-               /* radio */
-               tuner_info("  E2-4 video if        : %s\n",
-                          rif[(buf[3] & 0x0c) >> 2]);
-               tuner_info("  E7   vif agc output  : %s\n",
-                          (buf[3] & 0x80)
-                          ? ((buf[3] & 0x10) ? "fm-agc radio" :
-                                               "sif-agc radio")
-                          : "fm radio carrier afc");
-       } else {
-               /* video */
-               tuner_info("  E2-4 video if        : %s\n",
-                          vif[(buf[3] & 0x1c) >> 2]);
-               tuner_info("  E5   tuner gain      : %s\n",
-                          (buf[3] & 0x80)
-                          ? ((buf[3] & 0x20) ? "external" : "normal")
-                          : ((buf[3] & 0x20) ? "minimum"  : "normal"));
-               tuner_info("  E7   vif agc output  : %s\n",
-                          (buf[3] & 0x80) ? ((buf[3] & 0x20)
-                               ? "pin3 port, pin22 vif agc out"
-                               : "pin22 port, pin3 vif acg ext in")
-                               : "pin3+pin22 port");
-       }
-       tuner_info("--\n");
-}
-
-/* ---------------------------------------------------------------------- */
-
-static int tda9887_set_tvnorm(struct dvb_frontend *fe)
-{
-       struct tda9887_priv *priv = fe->analog_demod_priv;
-       struct tvnorm *norm = NULL;
-       char *buf = priv->data;
-       int i;
-
-       if (priv->mode == V4L2_TUNER_RADIO) {
-               if (priv->audmode == V4L2_TUNER_MODE_MONO)
-                       norm = &radio_mono;
-               else
-                       norm = &radio_stereo;
-       } else {
-               for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
-                       if (tvnorms[i].std & priv->std) {
-                               norm = tvnorms+i;
-                               break;
-                       }
-               }
-       }
-       if (NULL == norm) {
-               tuner_dbg("Unsupported tvnorm entry - audio muted\n");
-               return -1;
-       }
-
-       tuner_dbg("configure for: %s\n", norm->name);
-       buf[1] = norm->b;
-       buf[2] = norm->c;
-       buf[3] = norm->e;
-       return 0;
-}
-
-static unsigned int port1  = UNSET;
-static unsigned int port2  = UNSET;
-static unsigned int qss    = UNSET;
-static unsigned int adjust = UNSET;
-
-module_param(port1, int, 0644);
-module_param(port2, int, 0644);
-module_param(qss, int, 0644);
-module_param(adjust, int, 0644);
-
-static int tda9887_set_insmod(struct dvb_frontend *fe)
-{
-       struct tda9887_priv *priv = fe->analog_demod_priv;
-       char *buf = priv->data;
-
-       if (UNSET != port1) {
-               if (port1)
-                       buf[1] |= cOutputPort1Inactive;
-               else
-                       buf[1] &= ~cOutputPort1Inactive;
-       }
-       if (UNSET != port2) {
-               if (port2)
-                       buf[1] |= cOutputPort2Inactive;
-               else
-                       buf[1] &= ~cOutputPort2Inactive;
-       }
-
-       if (UNSET != qss) {
-               if (qss)
-                       buf[1] |= cQSS;
-               else
-                       buf[1] &= ~cQSS;
-       }
-
-       if (adjust < 0x20) {
-               buf[2] &= ~cTopMask;
-               buf[2] |= adjust;
-       }
-       return 0;
-}
-
-static int tda9887_do_config(struct dvb_frontend *fe)
-{
-       struct tda9887_priv *priv = fe->analog_demod_priv;
-       char *buf = priv->data;
-
-       if (priv->config & TDA9887_PORT1_ACTIVE)
-               buf[1] &= ~cOutputPort1Inactive;
-       if (priv->config & TDA9887_PORT1_INACTIVE)
-               buf[1] |= cOutputPort1Inactive;
-       if (priv->config & TDA9887_PORT2_ACTIVE)
-               buf[1] &= ~cOutputPort2Inactive;
-       if (priv->config & TDA9887_PORT2_INACTIVE)
-               buf[1] |= cOutputPort2Inactive;
-
-       if (priv->config & TDA9887_QSS)
-               buf[1] |= cQSS;
-       if (priv->config & TDA9887_INTERCARRIER)
-               buf[1] &= ~cQSS;
-
-       if (priv->config & TDA9887_AUTOMUTE)
-               buf[1] |= cAutoMuteFmActive;
-       if (priv->config & TDA9887_DEEMPHASIS_MASK) {
-               buf[2] &= ~0x60;
-               switch (priv->config & TDA9887_DEEMPHASIS_MASK) {
-               case TDA9887_DEEMPHASIS_NONE:
-                       buf[2] |= cDeemphasisOFF;
-                       break;
-               case TDA9887_DEEMPHASIS_50:
-                       buf[2] |= cDeemphasisON | cDeemphasis50;
-                       break;
-               case TDA9887_DEEMPHASIS_75:
-                       buf[2] |= cDeemphasisON | cDeemphasis75;
-                       break;
-               }
-       }
-       if (priv->config & TDA9887_TOP_SET) {
-               buf[2] &= ~cTopMask;
-               buf[2] |= (priv->config >> 8) & cTopMask;
-       }
-       if ((priv->config & TDA9887_INTERCARRIER_NTSC) &&
-           (priv->std & V4L2_STD_NTSC))
-               buf[1] &= ~cQSS;
-       if (priv->config & TDA9887_GATING_18)
-               buf[3] &= ~cGating_36;
-
-       if (priv->mode == V4L2_TUNER_RADIO) {
-               if (priv->config & TDA9887_RIF_41_3) {
-                       buf[3] &= ~cVideoIFMask;
-                       buf[3] |= cRadioIF_41_30;
-               }
-               if (priv->config & TDA9887_GAIN_NORMAL)
-                       buf[3] &= ~cTunerGainLow;
-       }
-
-       return 0;
-}
-
-/* ---------------------------------------------------------------------- */
-
-static int tda9887_status(struct dvb_frontend *fe)
-{
-       struct tda9887_priv *priv = fe->analog_demod_priv;
-       unsigned char buf[1];
-       int rc;
-
-       memset(buf,0,sizeof(buf));
-       if (1 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props,buf,1)))
-               tuner_info("i2c i/o error: rc == %d (should be 1)\n", rc);
-       dump_read_message(fe, buf);
-       return 0;
-}
-
-static void tda9887_configure(struct dvb_frontend *fe)
-{
-       struct tda9887_priv *priv = fe->analog_demod_priv;
-       int rc;
-
-       memset(priv->data,0,sizeof(priv->data));
-       tda9887_set_tvnorm(fe);
-
-       /* A note on the port settings:
-          These settings tend to depend on the specifics of the board.
-          By default they are set to inactive (bit value 1) by this driver,
-          overwriting any changes made by the tvnorm. This means that it
-          is the responsibility of the module using the tda9887 to set
-          these values in case of changes in the tvnorm.
-          In many cases port 2 should be made active (0) when selecting
-          SECAM-L, and port 2 should remain inactive (1) for SECAM-L'.
-
-          For the other standards the tda9887 application note says that
-          the ports should be set to active (0), but, again, that may
-          differ depending on the precise hardware configuration.
-        */
-       priv->data[1] |= cOutputPort1Inactive;
-       priv->data[1] |= cOutputPort2Inactive;
-
-       tda9887_do_config(fe);
-       tda9887_set_insmod(fe);
-
-       if (priv->standby)
-               priv->data[1] |= cForcedMuteAudioON;
-
-       tuner_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
-                 priv->data[1], priv->data[2], priv->data[3]);
-       if (debug > 1)
-               dump_write_message(fe, priv->data);
-
-       if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,priv->data,4)))
-               tuner_info("i2c i/o error: rc == %d (should be 4)\n", rc);
-
-       if (debug > 2) {
-               msleep_interruptible(1000);
-               tda9887_status(fe);
-       }
-}
-
-/* ---------------------------------------------------------------------- */
-
-static void tda9887_tuner_status(struct dvb_frontend *fe)
-{
-       struct tda9887_priv *priv = fe->analog_demod_priv;
-       tuner_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n",
-                  priv->data[1], priv->data[2], priv->data[3]);
-}
-
-static int tda9887_get_afc(struct dvb_frontend *fe)
-{
-       struct tda9887_priv *priv = fe->analog_demod_priv;
-       static int AFC_BITS_2_kHz[] = {
-               -12500,  -37500,  -62500,  -97500,
-               -112500, -137500, -162500, -187500,
-               187500,  162500,  137500,  112500,
-               97500 ,  62500,   37500 ,  12500
-       };
-       int afc=0;
-       __u8 reg = 0;
-
-       if (1 == tuner_i2c_xfer_recv(&priv->i2c_props,&reg,1))
-               afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];
-
-       return afc;
-}
-
-static void tda9887_standby(struct dvb_frontend *fe)
-{
-       struct tda9887_priv *priv = fe->analog_demod_priv;
-
-       priv->standby = true;
-
-       tda9887_configure(fe);
-}
-
-static void tda9887_set_params(struct dvb_frontend *fe,
-                              struct analog_parameters *params)
-{
-       struct tda9887_priv *priv = fe->analog_demod_priv;
-
-       priv->standby = false;
-       priv->mode    = params->mode;
-       priv->audmode = params->audmode;
-       priv->std     = params->std;
-       tda9887_configure(fe);
-}
-
-static int tda9887_set_config(struct dvb_frontend *fe, void *priv_cfg)
-{
-       struct tda9887_priv *priv = fe->analog_demod_priv;
-
-       priv->config = *(unsigned int *)priv_cfg;
-       tda9887_configure(fe);
-
-       return 0;
-}
-
-static void tda9887_release(struct dvb_frontend *fe)
-{
-       struct tda9887_priv *priv = fe->analog_demod_priv;
-
-       mutex_lock(&tda9887_list_mutex);
-
-       if (priv)
-               hybrid_tuner_release_state(priv);
-
-       mutex_unlock(&tda9887_list_mutex);
-
-       fe->analog_demod_priv = NULL;
-}
-
-static struct analog_demod_ops tda9887_ops = {
-       .info           = {
-               .name   = "tda9887",
-       },
-       .set_params     = tda9887_set_params,
-       .standby        = tda9887_standby,
-       .tuner_status   = tda9887_tuner_status,
-       .get_afc        = tda9887_get_afc,
-       .release        = tda9887_release,
-       .set_config     = tda9887_set_config,
-};
-
-struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
-                                   struct i2c_adapter *i2c_adap,
-                                   u8 i2c_addr)
-{
-       struct tda9887_priv *priv = NULL;
-       int instance;
-
-       mutex_lock(&tda9887_list_mutex);
-
-       instance = hybrid_tuner_request_state(struct tda9887_priv, priv,
-                                             hybrid_tuner_instance_list,
-                                             i2c_adap, i2c_addr, "tda9887");
-       switch (instance) {
-       case 0:
-               mutex_unlock(&tda9887_list_mutex);
-               return NULL;
-       case 1:
-               fe->analog_demod_priv = priv;
-               priv->standby = true;
-               tuner_info("tda988[5/6/7] found\n");
-               break;
-       default:
-               fe->analog_demod_priv = priv;
-               break;
-       }
-
-       mutex_unlock(&tda9887_list_mutex);
-
-       memcpy(&fe->ops.analog_ops, &tda9887_ops,
-              sizeof(struct analog_demod_ops));
-
-       return fe;
-}
-EXPORT_SYMBOL_GPL(tda9887_attach);
-
-MODULE_LICENSE("GPL");
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/common/tuners/tda9887.h b/drivers/media/common/tuners/tda9887.h
deleted file mode 100644 (file)
index acc419e..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-    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 __TDA9887_H__
-#define __TDA9887_H__
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-
-/* ------------------------------------------------------------------------ */
-#if defined(CONFIG_MEDIA_TUNER_TDA9887) || (defined(CONFIG_MEDIA_TUNER_TDA9887_MODULE) && defined(MODULE))
-extern struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
-                                          struct i2c_adapter *i2c_adap,
-                                          u8 i2c_addr);
-#else
-static inline struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
-                                                 struct i2c_adapter *i2c_adap,
-                                                 u8 i2c_addr)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* __TDA9887_H__ */
diff --git a/drivers/media/common/tuners/tea5761.c b/drivers/media/common/tuners/tea5761.c
deleted file mode 100644 (file)
index bf78cb9..0000000
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * For Philips TEA5761 FM Chip
- * I2C address is allways 0x20 (0x10 at 7-bit mode).
- *
- * Copyright (c) 2005-2007 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNUv2 General Public License
- *
- */
-
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/videodev2.h>
-#include <media/tuner.h>
-#include "tuner-i2c.h"
-#include "tea5761.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable verbose debug messages");
-
-struct tea5761_priv {
-       struct tuner_i2c_props i2c_props;
-
-       u32 frequency;
-       bool standby;
-};
-
-/*****************************************************************************/
-
-/***************************
- * TEA5761HN I2C registers *
- ***************************/
-
-/* INTREG - Read: bytes 0 and 1 / Write: byte 0 */
-
-       /* first byte for reading */
-#define TEA5761_INTREG_IFFLAG          0x10
-#define TEA5761_INTREG_LEVFLAG         0x8
-#define TEA5761_INTREG_FRRFLAG         0x2
-#define TEA5761_INTREG_BLFLAG          0x1
-
-       /* second byte for reading / byte for writing */
-#define TEA5761_INTREG_IFMSK           0x10
-#define TEA5761_INTREG_LEVMSK          0x8
-#define TEA5761_INTREG_FRMSK           0x2
-#define TEA5761_INTREG_BLMSK           0x1
-
-/* FRQSET - Read: bytes 2 and 3 / Write: byte 1 and 2 */
-
-       /* First byte */
-#define TEA5761_FRQSET_SEARCH_UP 0x80          /* 1=Station search from botton to up */
-#define TEA5761_FRQSET_SEARCH_MODE 0x40                /* 1=Search mode */
-
-       /* Bits 0-5 for divider MSB */
-
-       /* Second byte */
-       /* Bits 0-7 for divider LSB */
-
-/* TNCTRL - Read: bytes 4 and 5 / Write: Bytes 3 and 4 */
-
-       /* first byte */
-
-#define TEA5761_TNCTRL_PUPD_0  0x40    /* Power UP/Power Down MSB */
-#define TEA5761_TNCTRL_BLIM    0X20    /* 1= Japan Frequencies, 0= European frequencies */
-#define TEA5761_TNCTRL_SWPM    0x10    /* 1= software port is FRRFLAG */
-#define TEA5761_TNCTRL_IFCTC   0x08    /* 1= IF count time 15.02 ms, 0= IF count time 2.02 ms */
-#define TEA5761_TNCTRL_AFM     0x04
-#define TEA5761_TNCTRL_SMUTE   0x02    /* 1= Soft mute */
-#define TEA5761_TNCTRL_SNC     0x01
-
-       /* second byte */
-
-#define TEA5761_TNCTRL_MU      0x80    /* 1=Hard mute */
-#define TEA5761_TNCTRL_SSL_1   0x40
-#define TEA5761_TNCTRL_SSL_0   0x20
-#define TEA5761_TNCTRL_HLSI    0x10
-#define TEA5761_TNCTRL_MST     0x08    /* 1 = mono */
-#define TEA5761_TNCTRL_SWP     0x04
-#define TEA5761_TNCTRL_DTC     0x02    /* 1 = deemphasis 50 us, 0 = deemphasis 75 us */
-#define TEA5761_TNCTRL_AHLSI   0x01
-
-/* FRQCHECK - Read: bytes 6 and 7  */
-       /* First byte */
-
-       /* Bits 0-5 for divider MSB */
-
-       /* Second byte */
-       /* Bits 0-7 for divider LSB */
-
-/* TUNCHECK - Read: bytes 8 and 9  */
-
-       /* First byte */
-#define TEA5761_TUNCHECK_IF_MASK       0x7e    /* IF count */
-#define TEA5761_TUNCHECK_TUNTO         0x01
-
-       /* Second byte */
-#define TEA5761_TUNCHECK_LEV_MASK      0xf0    /* Level Count */
-#define TEA5761_TUNCHECK_LD            0x08
-#define TEA5761_TUNCHECK_STEREO                0x04
-
-/* TESTREG - Read: bytes 10 and 11 / Write: bytes 5 and 6 */
-
-       /* All zero = no test mode */
-
-/* MANID - Read: bytes 12 and 13 */
-
-       /* First byte - should be 0x10 */
-#define TEA5767_MANID_VERSION_MASK     0xf0    /* Version = 1 */
-#define TEA5767_MANID_ID_MSB_MASK      0x0f    /* Manufacurer ID - should be 0 */
-
-       /* Second byte - Should be 0x2b */
-
-#define TEA5767_MANID_ID_LSB_MASK      0xfe    /* Manufacturer ID - should be 0x15 */
-#define TEA5767_MANID_IDAV             0x01    /* 1 = Chip has ID, 0 = Chip has no ID */
-
-/* Chip ID - Read: bytes 14 and 15 */
-
-       /* First byte - should be 0x57 */
-
-       /* Second byte - should be 0x61 */
-
-/*****************************************************************************/
-
-#define FREQ_OFFSET 0 /* for TEA5767, it is 700 to give the right freq */
-static void tea5761_status_dump(unsigned char *buffer)
-{
-       unsigned int div, frq;
-
-       div = ((buffer[2] & 0x3f) << 8) | buffer[3];
-
-       frq = 1000 * (div * 32768 / 1000 + FREQ_OFFSET + 225) / 4;      /* Freq in KHz */
-
-       printk(KERN_INFO "tea5761: Frequency %d.%03d KHz (divider = 0x%04x)\n",
-              frq / 1000, frq % 1000, div);
-}
-
-/* Freq should be specifyed at 62.5 Hz */
-static int __set_radio_freq(struct dvb_frontend *fe,
-                           unsigned int freq,
-                           bool mono)
-{
-       struct tea5761_priv *priv = fe->tuner_priv;
-       unsigned int frq = freq;
-       unsigned char buffer[7] = {0, 0, 0, 0, 0, 0, 0 };
-       unsigned div;
-       int rc;
-
-       tuner_dbg("radio freq counter %d\n", frq);
-
-       if (priv->standby) {
-               tuner_dbg("TEA5761 set to standby mode\n");
-               buffer[5] |= TEA5761_TNCTRL_MU;
-       } else {
-               buffer[4] |= TEA5761_TNCTRL_PUPD_0;
-       }
-
-
-       if (mono) {
-               tuner_dbg("TEA5761 set to mono\n");
-               buffer[5] |= TEA5761_TNCTRL_MST;
-       } else {
-               tuner_dbg("TEA5761 set to stereo\n");
-       }
-
-       div = (1000 * (frq * 4 / 16 + 700 + 225) ) >> 15;
-       buffer[1] = (div >> 8) & 0x3f;
-       buffer[2] = div & 0xff;
-
-       if (debug)
-               tea5761_status_dump(buffer);
-
-       if (7 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 7)))
-               tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
-
-       priv->frequency = frq * 125 / 2;
-
-       return 0;
-}
-
-static int set_radio_freq(struct dvb_frontend *fe,
-                         struct analog_parameters *params)
-{
-       struct tea5761_priv *priv = fe->analog_demod_priv;
-
-       priv->standby = false;
-
-       return __set_radio_freq(fe, params->frequency,
-                               params->audmode == V4L2_TUNER_MODE_MONO);
-}
-
-static int set_radio_sleep(struct dvb_frontend *fe)
-{
-       struct tea5761_priv *priv = fe->analog_demod_priv;
-
-       priv->standby = true;
-
-       return __set_radio_freq(fe, priv->frequency, false);
-}
-
-static int tea5761_read_status(struct dvb_frontend *fe, char *buffer)
-{
-       struct tea5761_priv *priv = fe->tuner_priv;
-       int rc;
-
-       memset(buffer, 0, 16);
-       if (16 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 16))) {
-               tuner_warn("i2c i/o error: rc == %d (should be 16)\n", rc);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static inline int tea5761_signal(struct dvb_frontend *fe, const char *buffer)
-{
-       struct tea5761_priv *priv = fe->tuner_priv;
-
-       int signal = ((buffer[9] & TEA5761_TUNCHECK_LEV_MASK) << (13 - 4));
-
-       tuner_dbg("Signal strength: %d\n", signal);
-
-       return signal;
-}
-
-static inline int tea5761_stereo(struct dvb_frontend *fe, const char *buffer)
-{
-       struct tea5761_priv *priv = fe->tuner_priv;
-
-       int stereo = buffer[9] & TEA5761_TUNCHECK_STEREO;
-
-       tuner_dbg("Radio ST GET = %02x\n", stereo);
-
-       return (stereo ? V4L2_TUNER_SUB_STEREO : 0);
-}
-
-static int tea5761_get_status(struct dvb_frontend *fe, u32 *status)
-{
-       unsigned char buffer[16];
-
-       *status = 0;
-
-       if (0 == tea5761_read_status(fe, buffer)) {
-               if (tea5761_signal(fe, buffer))
-                       *status = TUNER_STATUS_LOCKED;
-               if (tea5761_stereo(fe, buffer))
-                       *status |= TUNER_STATUS_STEREO;
-       }
-
-       return 0;
-}
-
-static int tea5761_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       unsigned char buffer[16];
-
-       *strength = 0;
-
-       if (0 == tea5761_read_status(fe, buffer))
-               *strength = tea5761_signal(fe, buffer);
-
-       return 0;
-}
-
-int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr)
-{
-       unsigned char buffer[16];
-       int rc;
-       struct tuner_i2c_props i2c = { .adap = i2c_adap, .addr = i2c_addr };
-
-       if (16 != (rc = tuner_i2c_xfer_recv(&i2c, buffer, 16))) {
-               printk(KERN_WARNING "it is not a TEA5761. Received %i chars.\n", rc);
-               return -EINVAL;
-       }
-
-       if ((buffer[13] != 0x2b) || (buffer[14] != 0x57) || (buffer[15] != 0x061)) {
-               printk(KERN_WARNING "Manufacturer ID= 0x%02x, Chip ID = %02x%02x."
-                                   " It is not a TEA5761\n",
-                                   buffer[13], buffer[14], buffer[15]);
-               return -EINVAL;
-       }
-       printk(KERN_WARNING "tea5761: TEA%02x%02x detected. "
-                           "Manufacturer ID= 0x%02x\n",
-                           buffer[14], buffer[15], buffer[13]);
-
-       return 0;
-}
-
-static int tea5761_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-
-       return 0;
-}
-
-static int tea5761_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct tea5761_priv *priv = fe->tuner_priv;
-       *frequency = priv->frequency;
-       return 0;
-}
-
-static struct dvb_tuner_ops tea5761_tuner_ops = {
-       .info = {
-               .name           = "tea5761", // Philips TEA5761HN FM Radio
-       },
-       .set_analog_params = set_radio_freq,
-       .sleep             = set_radio_sleep,
-       .release           = tea5761_release,
-       .get_frequency     = tea5761_get_frequency,
-       .get_status        = tea5761_get_status,
-       .get_rf_strength   = tea5761_get_rf_strength,
-};
-
-struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe,
-                                   struct i2c_adapter* i2c_adap,
-                                   u8 i2c_addr)
-{
-       struct tea5761_priv *priv = NULL;
-
-       if (tea5761_autodetection(i2c_adap, i2c_addr) != 0)
-               return NULL;
-
-       priv = kzalloc(sizeof(struct tea5761_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-       fe->tuner_priv = priv;
-
-       priv->i2c_props.addr = i2c_addr;
-       priv->i2c_props.adap = i2c_adap;
-       priv->i2c_props.name = "tea5761";
-
-       memcpy(&fe->ops.tuner_ops, &tea5761_tuner_ops,
-              sizeof(struct dvb_tuner_ops));
-
-       tuner_info("type set to %s\n", "Philips TEA5761HN FM Radio");
-
-       return fe;
-}
-
-
-EXPORT_SYMBOL_GPL(tea5761_attach);
-EXPORT_SYMBOL_GPL(tea5761_autodetection);
-
-MODULE_DESCRIPTION("Philips TEA5761 FM tuner driver");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/tea5761.h b/drivers/media/common/tuners/tea5761.h
deleted file mode 100644 (file)
index 2e2ff82..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-    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 __TEA5761_H__
-#define __TEA5761_H__
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-
-#if defined(CONFIG_MEDIA_TUNER_TEA5761) || (defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE) && defined(MODULE))
-extern int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr);
-
-extern struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe,
-                                          struct i2c_adapter* i2c_adap,
-                                          u8 i2c_addr);
-#else
-static inline int tea5761_autodetection(struct i2c_adapter* i2c_adap,
-                                       u8 i2c_addr)
-{
-       printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
-              __func__);
-       return -EINVAL;
-}
-
-static inline struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe,
-                                                  struct i2c_adapter* i2c_adap,
-                                                  u8 i2c_addr)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* __TEA5761_H__ */
diff --git a/drivers/media/common/tuners/tea5767.c b/drivers/media/common/tuners/tea5767.c
deleted file mode 100644 (file)
index 36e85d8..0000000
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
- * I2C address is allways 0xC0.
- *
- *
- * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNU General Public License
- *
- * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa
- * from their contributions on DScaler.
- */
-
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/videodev2.h>
-#include "tuner-i2c.h"
-#include "tea5767.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable verbose debug messages");
-
-/*****************************************************************************/
-
-struct tea5767_priv {
-       struct tuner_i2c_props  i2c_props;
-       u32                     frequency;
-       struct tea5767_ctrl     ctrl;
-};
-
-/*****************************************************************************/
-
-/******************************
- * Write mode register values *
- ******************************/
-
-/* First register */
-#define TEA5767_MUTE           0x80    /* Mutes output */
-#define TEA5767_SEARCH         0x40    /* Activates station search */
-/* Bits 0-5 for divider MSB */
-
-/* Second register */
-/* Bits 0-7 for divider LSB */
-
-/* Third register */
-
-/* Station search from botton to up */
-#define TEA5767_SEARCH_UP      0x80
-
-/* Searches with ADC output = 10 */
-#define TEA5767_SRCH_HIGH_LVL  0x60
-
-/* Searches with ADC output = 10 */
-#define TEA5767_SRCH_MID_LVL   0x40
-
-/* Searches with ADC output = 5 */
-#define TEA5767_SRCH_LOW_LVL   0x20
-
-/* if on, div=4*(Frf+Fif)/Fref otherwise, div=4*(Frf-Fif)/Freq) */
-#define TEA5767_HIGH_LO_INJECT 0x10
-
-/* Disable stereo */
-#define TEA5767_MONO           0x08
-
-/* Disable right channel and turns to mono */
-#define TEA5767_MUTE_RIGHT     0x04
-
-/* Disable left channel and turns to mono */
-#define TEA5767_MUTE_LEFT      0x02
-
-#define TEA5767_PORT1_HIGH     0x01
-
-/* Fourth register */
-#define TEA5767_PORT2_HIGH     0x80
-/* Chips stops working. Only I2C bus remains on */
-#define TEA5767_STDBY          0x40
-
-/* Japan freq (76-108 MHz. If disabled, 87.5-108 MHz */
-#define TEA5767_JAPAN_BAND     0x20
-
-/* Unselected means 32.768 KHz freq as reference. Otherwise Xtal at 13 MHz */
-#define TEA5767_XTAL_32768     0x10
-
-/* Cuts weak signals */
-#define TEA5767_SOFT_MUTE      0x08
-
-/* Activates high cut control */
-#define TEA5767_HIGH_CUT_CTRL  0x04
-
-/* Activates stereo noise control */
-#define TEA5767_ST_NOISE_CTL   0x02
-
-/* If activate PORT 1 indicates SEARCH or else it is used as PORT1 */
-#define TEA5767_SRCH_IND       0x01
-
-/* Fifth register */
-
-/* By activating, it will use Xtal at 13 MHz as reference for divider */
-#define TEA5767_PLLREF_ENABLE  0x80
-
-/* By activating, deemphasis=50, or else, deemphasis of 50us */
-#define TEA5767_DEEMPH_75      0X40
-
-/*****************************
- * Read mode register values *
- *****************************/
-
-/* First register */
-#define TEA5767_READY_FLAG_MASK        0x80
-#define TEA5767_BAND_LIMIT_MASK        0X40
-/* Bits 0-5 for divider MSB after search or preset */
-
-/* Second register */
-/* Bits 0-7 for divider LSB after search or preset */
-
-/* Third register */
-#define TEA5767_STEREO_MASK    0x80
-#define TEA5767_IF_CNTR_MASK   0x7f
-
-/* Fourth register */
-#define TEA5767_ADC_LEVEL_MASK 0xf0
-
-/* should be 0 */
-#define TEA5767_CHIP_ID_MASK   0x0f
-
-/* Fifth register */
-/* Reserved for future extensions */
-#define TEA5767_RESERVED_MASK  0xff
-
-/*****************************************************************************/
-
-static void tea5767_status_dump(struct tea5767_priv *priv,
-                               unsigned char *buffer)
-{
-       unsigned int div, frq;
-
-       if (TEA5767_READY_FLAG_MASK & buffer[0])
-               tuner_info("Ready Flag ON\n");
-       else
-               tuner_info("Ready Flag OFF\n");
-
-       if (TEA5767_BAND_LIMIT_MASK & buffer[0])
-               tuner_info("Tuner at band limit\n");
-       else
-               tuner_info("Tuner not at band limit\n");
-
-       div = ((buffer[0] & 0x3f) << 8) | buffer[1];
-
-       switch (priv->ctrl.xtal_freq) {
-       case TEA5767_HIGH_LO_13MHz:
-               frq = (div * 50000 - 700000 - 225000) / 4;      /* Freq in KHz */
-               break;
-       case TEA5767_LOW_LO_13MHz:
-               frq = (div * 50000 + 700000 + 225000) / 4;      /* Freq in KHz */
-               break;
-       case TEA5767_LOW_LO_32768:
-               frq = (div * 32768 + 700000 + 225000) / 4;      /* Freq in KHz */
-               break;
-       case TEA5767_HIGH_LO_32768:
-       default:
-               frq = (div * 32768 - 700000 - 225000) / 4;      /* Freq in KHz */
-               break;
-       }
-       buffer[0] = (div >> 8) & 0x3f;
-       buffer[1] = div & 0xff;
-
-       tuner_info("Frequency %d.%03d KHz (divider = 0x%04x)\n",
-                  frq / 1000, frq % 1000, div);
-
-       if (TEA5767_STEREO_MASK & buffer[2])
-               tuner_info("Stereo\n");
-       else
-               tuner_info("Mono\n");
-
-       tuner_info("IF Counter = %d\n", buffer[2] & TEA5767_IF_CNTR_MASK);
-
-       tuner_info("ADC Level = %d\n",
-                  (buffer[3] & TEA5767_ADC_LEVEL_MASK) >> 4);
-
-       tuner_info("Chip ID = %d\n", (buffer[3] & TEA5767_CHIP_ID_MASK));
-
-       tuner_info("Reserved = 0x%02x\n",
-                  (buffer[4] & TEA5767_RESERVED_MASK));
-}
-
-/* Freq should be specifyed at 62.5 Hz */
-static int set_radio_freq(struct dvb_frontend *fe,
-                         struct analog_parameters *params)
-{
-       struct tea5767_priv *priv = fe->tuner_priv;
-       unsigned int frq = params->frequency;
-       unsigned char buffer[5];
-       unsigned div;
-       int rc;
-
-       tuner_dbg("radio freq = %d.%03d MHz\n", frq/16000,(frq/16)%1000);
-
-       buffer[2] = 0;
-
-       if (priv->ctrl.port1)
-               buffer[2] |= TEA5767_PORT1_HIGH;
-
-       if (params->audmode == V4L2_TUNER_MODE_MONO) {
-               tuner_dbg("TEA5767 set to mono\n");
-               buffer[2] |= TEA5767_MONO;
-       } else {
-               tuner_dbg("TEA5767 set to stereo\n");
-       }
-
-
-       buffer[3] = 0;
-
-       if (priv->ctrl.port2)
-               buffer[3] |= TEA5767_PORT2_HIGH;
-
-       if (priv->ctrl.high_cut)
-               buffer[3] |= TEA5767_HIGH_CUT_CTRL;
-
-       if (priv->ctrl.st_noise)
-               buffer[3] |= TEA5767_ST_NOISE_CTL;
-
-       if (priv->ctrl.soft_mute)
-               buffer[3] |= TEA5767_SOFT_MUTE;
-
-       if (priv->ctrl.japan_band)
-               buffer[3] |= TEA5767_JAPAN_BAND;
-
-       buffer[4] = 0;
-
-       if (priv->ctrl.deemph_75)
-               buffer[4] |= TEA5767_DEEMPH_75;
-
-       if (priv->ctrl.pllref)
-               buffer[4] |= TEA5767_PLLREF_ENABLE;
-
-
-       /* Rounds freq to next decimal value - for 62.5 KHz step */
-       /* frq = 20*(frq/16)+radio_frq[frq%16]; */
-
-       switch (priv->ctrl.xtal_freq) {
-       case TEA5767_HIGH_LO_13MHz:
-               tuner_dbg("radio HIGH LO inject xtal @ 13 MHz\n");
-               buffer[2] |= TEA5767_HIGH_LO_INJECT;
-               div = (frq * (4000 / 16) + 700000 + 225000 + 25000) / 50000;
-               break;
-       case TEA5767_LOW_LO_13MHz:
-               tuner_dbg("radio LOW LO inject xtal @ 13 MHz\n");
-
-               div = (frq * (4000 / 16) - 700000 - 225000 + 25000) / 50000;
-               break;
-       case TEA5767_LOW_LO_32768:
-               tuner_dbg("radio LOW LO inject xtal @ 32,768 MHz\n");
-               buffer[3] |= TEA5767_XTAL_32768;
-               /* const 700=4000*175 Khz - to adjust freq to right value */
-               div = ((frq * (4000 / 16) - 700000 - 225000) + 16384) >> 15;
-               break;
-       case TEA5767_HIGH_LO_32768:
-       default:
-               tuner_dbg("radio HIGH LO inject xtal @ 32,768 MHz\n");
-
-               buffer[2] |= TEA5767_HIGH_LO_INJECT;
-               buffer[3] |= TEA5767_XTAL_32768;
-               div = ((frq * (4000 / 16) + 700000 + 225000) + 16384) >> 15;
-               break;
-       }
-       buffer[0] = (div >> 8) & 0x3f;
-       buffer[1] = div & 0xff;
-
-       if (5 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 5)))
-               tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
-
-       if (debug) {
-               if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5)))
-                       tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
-               else
-                       tea5767_status_dump(priv, buffer);
-       }
-
-       priv->frequency = frq * 125 / 2;
-
-       return 0;
-}
-
-static int tea5767_read_status(struct dvb_frontend *fe, char *buffer)
-{
-       struct tea5767_priv *priv = fe->tuner_priv;
-       int rc;
-
-       memset(buffer, 0, 5);
-       if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5))) {
-               tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static inline int tea5767_signal(struct dvb_frontend *fe, const char *buffer)
-{
-       struct tea5767_priv *priv = fe->tuner_priv;
-
-       int signal = ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << 8);
-
-       tuner_dbg("Signal strength: %d\n", signal);
-
-       return signal;
-}
-
-static inline int tea5767_stereo(struct dvb_frontend *fe, const char *buffer)
-{
-       struct tea5767_priv *priv = fe->tuner_priv;
-
-       int stereo = buffer[2] & TEA5767_STEREO_MASK;
-
-       tuner_dbg("Radio ST GET = %02x\n", stereo);
-
-       return (stereo ? V4L2_TUNER_SUB_STEREO : 0);
-}
-
-static int tea5767_get_status(struct dvb_frontend *fe, u32 *status)
-{
-       unsigned char buffer[5];
-
-       *status = 0;
-
-       if (0 == tea5767_read_status(fe, buffer)) {
-               if (tea5767_signal(fe, buffer))
-                       *status = TUNER_STATUS_LOCKED;
-               if (tea5767_stereo(fe, buffer))
-                       *status |= TUNER_STATUS_STEREO;
-       }
-
-       return 0;
-}
-
-static int tea5767_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       unsigned char buffer[5];
-
-       *strength = 0;
-
-       if (0 == tea5767_read_status(fe, buffer))
-               *strength = tea5767_signal(fe, buffer);
-
-       return 0;
-}
-
-static int tea5767_standby(struct dvb_frontend *fe)
-{
-       unsigned char buffer[5];
-       struct tea5767_priv *priv = fe->tuner_priv;
-       unsigned div, rc;
-
-       div = (87500 * 4 + 700 + 225 + 25) / 50; /* Set frequency to 87.5 MHz */
-       buffer[0] = (div >> 8) & 0x3f;
-       buffer[1] = div & 0xff;
-       buffer[2] = TEA5767_PORT1_HIGH;
-       buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL |
-                   TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND | TEA5767_STDBY;
-       buffer[4] = 0;
-
-       if (5 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 5)))
-               tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
-
-       return 0;
-}
-
-int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr)
-{
-       struct tuner_i2c_props i2c = { .adap = i2c_adap, .addr = i2c_addr };
-       unsigned char buffer[7] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-       int rc;
-
-       if ((rc = tuner_i2c_xfer_recv(&i2c, buffer, 7))< 5) {
-               printk(KERN_WARNING "It is not a TEA5767. Received %i bytes.\n", rc);
-               return -EINVAL;
-       }
-
-       /* 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] &&
-           buffer[0] == buffer[3] && buffer[0] == buffer[4]) {
-               printk(KERN_WARNING "All bytes are equal. It is not a TEA5767\n");
-               return -EINVAL;
-       }
-
-       /*  Status bytes:
-        *  Byte 4: bit 3:1 : CI (Chip Identification) == 0
-        *          bit 0   : internally set to 0
-        *  Byte 5: bit 7:0 : == 0
-        */
-       if (((buffer[3] & 0x0f) != 0x00) || (buffer[4] != 0x00)) {
-               printk(KERN_WARNING "Chip ID is not zero. It is not a TEA5767\n");
-               return -EINVAL;
-       }
-
-
-       return 0;
-}
-
-static int tea5767_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-
-       return 0;
-}
-
-static int tea5767_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct tea5767_priv *priv = fe->tuner_priv;
-       *frequency = priv->frequency;
-
-       return 0;
-}
-
-static int tea5767_set_config (struct dvb_frontend *fe, void *priv_cfg)
-{
-       struct tea5767_priv *priv = fe->tuner_priv;
-
-       memcpy(&priv->ctrl, priv_cfg, sizeof(priv->ctrl));
-
-       return 0;
-}
-
-static struct dvb_tuner_ops tea5767_tuner_ops = {
-       .info = {
-               .name           = "tea5767", // Philips TEA5767HN FM Radio
-       },
-
-       .set_analog_params = set_radio_freq,
-       .set_config        = tea5767_set_config,
-       .sleep             = tea5767_standby,
-       .release           = tea5767_release,
-       .get_frequency     = tea5767_get_frequency,
-       .get_status        = tea5767_get_status,
-       .get_rf_strength   = tea5767_get_rf_strength,
-};
-
-struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe,
-                                   struct i2c_adapter* i2c_adap,
-                                   u8 i2c_addr)
-{
-       struct tea5767_priv *priv = NULL;
-
-       priv = kzalloc(sizeof(struct tea5767_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-       fe->tuner_priv = priv;
-
-       priv->i2c_props.addr  = i2c_addr;
-       priv->i2c_props.adap  = i2c_adap;
-       priv->i2c_props.name  = "tea5767";
-
-       priv->ctrl.xtal_freq  = TEA5767_HIGH_LO_32768;
-       priv->ctrl.port1      = 1;
-       priv->ctrl.port2      = 1;
-       priv->ctrl.high_cut   = 1;
-       priv->ctrl.st_noise   = 1;
-       priv->ctrl.japan_band = 1;
-
-       memcpy(&fe->ops.tuner_ops, &tea5767_tuner_ops,
-              sizeof(struct dvb_tuner_ops));
-
-       tuner_info("type set to %s\n", "Philips TEA5767HN FM Radio");
-
-       return fe;
-}
-
-EXPORT_SYMBOL_GPL(tea5767_attach);
-EXPORT_SYMBOL_GPL(tea5767_autodetection);
-
-MODULE_DESCRIPTION("Philips TEA5767 FM tuner driver");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/tea5767.h b/drivers/media/common/tuners/tea5767.h
deleted file mode 100644 (file)
index d30ab1b..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
-    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 __TEA5767_H__
-#define __TEA5767_H__
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-
-enum tea5767_xtal {
-       TEA5767_LOW_LO_32768    = 0,
-       TEA5767_HIGH_LO_32768   = 1,
-       TEA5767_LOW_LO_13MHz    = 2,
-       TEA5767_HIGH_LO_13MHz   = 3,
-};
-
-struct tea5767_ctrl {
-       unsigned int            port1:1;
-       unsigned int            port2:1;
-       unsigned int            high_cut:1;
-       unsigned int            st_noise:1;
-       unsigned int            soft_mute:1;
-       unsigned int            japan_band:1;
-       unsigned int            deemph_75:1;
-       unsigned int            pllref:1;
-       enum tea5767_xtal       xtal_freq;
-};
-
-#if defined(CONFIG_MEDIA_TUNER_TEA5767) || (defined(CONFIG_MEDIA_TUNER_TEA5767_MODULE) && defined(MODULE))
-extern int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr);
-
-extern struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe,
-                                          struct i2c_adapter* i2c_adap,
-                                          u8 i2c_addr);
-#else
-static inline int tea5767_autodetection(struct i2c_adapter* i2c_adap,
-                                       u8 i2c_addr)
-{
-       printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
-              __func__);
-       return -EINVAL;
-}
-
-static inline struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe,
-                                                  struct i2c_adapter* i2c_adap,
-                                                  u8 i2c_addr)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* __TEA5767_H__ */
diff --git a/drivers/media/common/tuners/tua9001.c b/drivers/media/common/tuners/tua9001.c
deleted file mode 100644 (file)
index de26070..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Infineon TUA 9001 silicon tuner driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- *
- *    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.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "tua9001.h"
-#include "tua9001_priv.h"
-
-/* write register */
-static int tua9001_wr_reg(struct tua9001_priv *priv, u8 reg, u16 val)
-{
-       int ret;
-       u8 buf[3] = { reg, (val >> 8) & 0xff, (val >> 0) & 0xff };
-       struct i2c_msg msg[1] = {
-               {
-                       .addr = priv->cfg->i2c_addr,
-                       .flags = 0,
-                       .len = sizeof(buf),
-                       .buf = buf,
-               }
-       };
-
-       ret = i2c_transfer(priv->i2c, msg, 1);
-       if (ret == 1) {
-               ret = 0;
-       } else {
-               printk(KERN_WARNING "%s: I2C wr failed=%d reg=%02x\n",
-                               __func__, ret, reg);
-               ret = -EREMOTEIO;
-       }
-
-       return ret;
-}
-
-static int tua9001_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-
-       return 0;
-}
-
-static int tua9001_init(struct dvb_frontend *fe)
-{
-       struct tua9001_priv *priv = fe->tuner_priv;
-       int ret = 0;
-       u8 i;
-       struct reg_val data[] = {
-               { 0x1e, 0x6512 },
-               { 0x25, 0xb888 },
-               { 0x39, 0x5460 },
-               { 0x3b, 0x00c0 },
-               { 0x3a, 0xf000 },
-               { 0x08, 0x0000 },
-               { 0x32, 0x0030 },
-               { 0x41, 0x703a },
-               { 0x40, 0x1c78 },
-               { 0x2c, 0x1c00 },
-               { 0x36, 0xc013 },
-               { 0x37, 0x6f18 },
-               { 0x27, 0x0008 },
-               { 0x2a, 0x0001 },
-               { 0x34, 0x0a40 },
-       };
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c-gate */
-
-       for (i = 0; i < ARRAY_SIZE(data); i++) {
-               ret = tua9001_wr_reg(priv, data[i].reg, data[i].val);
-               if (ret)
-                       break;
-       }
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c-gate */
-
-       if (ret < 0)
-               pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int tua9001_set_params(struct dvb_frontend *fe)
-{
-       struct tua9001_priv *priv = fe->tuner_priv;
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       int ret, i;
-       u16 val;
-       u32 frequency;
-       struct reg_val data[2];
-
-       pr_debug("%s: delivery_system=%d frequency=%d bandwidth_hz=%d\n",
-                       __func__, c->delivery_system, c->frequency,
-                       c->bandwidth_hz);
-
-       switch (c->delivery_system) {
-       case SYS_DVBT:
-               switch (c->bandwidth_hz) {
-               case 8000000:
-                       val  = 0x0000;
-                       break;
-               case 7000000:
-                       val  = 0x1000;
-                       break;
-               case 6000000:
-                       val  = 0x2000;
-                       break;
-               case 5000000:
-                       val  = 0x3000;
-                       break;
-               default:
-                       ret = -EINVAL;
-                       goto err;
-               }
-               break;
-       default:
-               ret = -EINVAL;
-               goto err;
-       }
-
-       data[0].reg = 0x04;
-       data[0].val = val;
-
-       frequency = (c->frequency - 150000000);
-       frequency /= 100;
-       frequency *= 48;
-       frequency /= 10000;
-
-       data[1].reg = 0x1f;
-       data[1].val = frequency;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c-gate */
-
-       for (i = 0; i < ARRAY_SIZE(data); i++) {
-               ret = tua9001_wr_reg(priv, data[i].reg, data[i].val);
-               if (ret < 0)
-                       break;
-       }
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c-gate */
-
-err:
-       if (ret < 0)
-               pr_debug("%s: failed=%d\n", __func__, ret);
-
-       return ret;
-}
-
-static int tua9001_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       *frequency = 0; /* Zero-IF */
-
-       return 0;
-}
-
-static const struct dvb_tuner_ops tua9001_tuner_ops = {
-       .info = {
-               .name           = "Infineon TUA 9001",
-
-               .frequency_min  = 170000000,
-               .frequency_max  = 862000000,
-               .frequency_step = 0,
-       },
-
-       .release = tua9001_release,
-
-       .init = tua9001_init,
-       .set_params = tua9001_set_params,
-
-       .get_if_frequency = tua9001_get_if_frequency,
-};
-
-struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe,
-               struct i2c_adapter *i2c, struct tua9001_config *cfg)
-{
-       struct tua9001_priv *priv = NULL;
-
-       priv = kzalloc(sizeof(struct tua9001_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->cfg = cfg;
-       priv->i2c = i2c;
-
-       printk(KERN_INFO "Infineon TUA 9001 successfully attached.");
-
-       memcpy(&fe->ops.tuner_ops, &tua9001_tuner_ops,
-                       sizeof(struct dvb_tuner_ops));
-
-       fe->tuner_priv = priv;
-       return fe;
-}
-EXPORT_SYMBOL(tua9001_attach);
-
-MODULE_DESCRIPTION("Infineon TUA 9001 silicon tuner driver");
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/tua9001.h b/drivers/media/common/tuners/tua9001.h
deleted file mode 100644 (file)
index 38d6ae7..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Infineon TUA 9001 silicon tuner driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- *
- *    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.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef TUA9001_H
-#define TUA9001_H
-
-#include "dvb_frontend.h"
-
-struct tua9001_config {
-       /*
-        * I2C address
-        */
-       u8 i2c_addr;
-};
-
-#if defined(CONFIG_MEDIA_TUNER_TUA9001) || \
-       (defined(CONFIG_MEDIA_TUNER_TUA9001_MODULE) && defined(MODULE))
-extern struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe,
-               struct i2c_adapter *i2c, struct tua9001_config *cfg);
-#else
-static inline struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe,
-               struct i2c_adapter *i2c, struct tua9001_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif
diff --git a/drivers/media/common/tuners/tua9001_priv.h b/drivers/media/common/tuners/tua9001_priv.h
deleted file mode 100644 (file)
index 73cc1ce..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Infineon TUA 9001 silicon tuner driver
- *
- * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
- *
- *    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.,
- *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef TUA9001_PRIV_H
-#define TUA9001_PRIV_H
-
-struct reg_val {
-       u8 reg;
-       u16 val;
-};
-
-struct tua9001_priv {
-       struct tua9001_config *cfg;
-       struct i2c_adapter *i2c;
-};
-
-#endif
diff --git a/drivers/media/common/tuners/tuner-i2c.h b/drivers/media/common/tuners/tuner-i2c.h
deleted file mode 100644 (file)
index 18f0056..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
-    tuner-i2c.h - i2c interface for different tuners
-
-    Copyright (C) 2007 Michael Krufky (mkrufky@linuxtv.org)
-
-    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 __TUNER_I2C_H__
-#define __TUNER_I2C_H__
-
-#include <linux/i2c.h>
-#include <linux/slab.h>
-
-struct tuner_i2c_props {
-       u8 addr;
-       struct i2c_adapter *adap;
-
-       /* used for tuner instance management */
-       int count;
-       char *name;
-};
-
-static inline int tuner_i2c_xfer_send(struct tuner_i2c_props *props, char *buf, int len)
-{
-       struct i2c_msg msg = { .addr = props->addr, .flags = 0,
-                              .buf = buf, .len = len };
-       int ret = i2c_transfer(props->adap, &msg, 1);
-
-       return (ret == 1) ? len : ret;
-}
-
-static inline int tuner_i2c_xfer_recv(struct tuner_i2c_props *props, char *buf, int len)
-{
-       struct i2c_msg msg = { .addr = props->addr, .flags = I2C_M_RD,
-                              .buf = buf, .len = len };
-       int ret = i2c_transfer(props->adap, &msg, 1);
-
-       return (ret == 1) ? len : ret;
-}
-
-static inline int tuner_i2c_xfer_send_recv(struct tuner_i2c_props *props,
-                                          char *obuf, int olen,
-                                          char *ibuf, int ilen)
-{
-       struct i2c_msg msg[2] = { { .addr = props->addr, .flags = 0,
-                                   .buf = obuf, .len = olen },
-                                 { .addr = props->addr, .flags = I2C_M_RD,
-                                   .buf = ibuf, .len = ilen } };
-       int ret = i2c_transfer(props->adap, msg, 2);
-
-       return (ret == 2) ? ilen : ret;
-}
-
-/* Callers must declare as a global for the module:
- *
- * static LIST_HEAD(hybrid_tuner_instance_list);
- *
- * hybrid_tuner_instance_list should be the third argument
- * passed into hybrid_tuner_request_state().
- *
- * state structure must contain the following:
- *
- *     struct list_head        hybrid_tuner_instance_list;
- *     struct tuner_i2c_props  i2c_props;
- *
- * hybrid_tuner_instance_list (both within state structure and globally)
- * is only required if the driver is using hybrid_tuner_request_state
- * and hybrid_tuner_release_state to manage state sharing between
- * multiple instances of hybrid tuners.
- */
-
-#define tuner_printk(kernlvl, i2cprops, fmt, arg...) do {              \
-       printk(kernlvl "%s %d-%04x: " fmt, i2cprops.name,               \
-                       i2cprops.adap ?                                 \
-                               i2c_adapter_id(i2cprops.adap) : -1,     \
-                       i2cprops.addr, ##arg);                          \
-        } while (0)
-
-/* TO DO: convert all callers of these macros to pass in
- * struct tuner_i2c_props, then remove the macro wrappers */
-
-#define __tuner_warn(i2cprops, fmt, arg...) do {                       \
-       tuner_printk(KERN_WARNING, i2cprops, fmt, ##arg);               \
-       } while (0)
-
-#define __tuner_info(i2cprops, fmt, arg...) do {                       \
-       tuner_printk(KERN_INFO, i2cprops, fmt, ##arg);                  \
-       } while (0)
-
-#define __tuner_err(i2cprops, fmt, arg...) do {                                \
-       tuner_printk(KERN_ERR, i2cprops, fmt, ##arg);                   \
-       } while (0)
-
-#define __tuner_dbg(i2cprops, fmt, arg...) do {                                \
-       if ((debug))                                                    \
-               tuner_printk(KERN_DEBUG, i2cprops, fmt, ##arg);         \
-       } while (0)
-
-#define tuner_warn(fmt, arg...) __tuner_warn(priv->i2c_props, fmt, ##arg)
-#define tuner_info(fmt, arg...) __tuner_info(priv->i2c_props, fmt, ##arg)
-#define tuner_err(fmt, arg...) __tuner_err(priv->i2c_props, fmt, ##arg)
-#define tuner_dbg(fmt, arg...) __tuner_dbg(priv->i2c_props, fmt, ##arg)
-
-/****************************************************************************/
-
-/* The return value of hybrid_tuner_request_state indicates the number of
- * instances using this tuner object.
- *
- * 0 - no instances, indicates an error - kzalloc must have failed
- *
- * 1 - one instance, indicates that the tuner object was created successfully
- *
- * 2 (or more) instances, indicates that an existing tuner object was found
- */
-
-#define hybrid_tuner_request_state(type, state, list, i2cadap, i2caddr, devname)\
-({                                                                     \
-       int __ret = 0;                                                  \
-       list_for_each_entry(state, &list, hybrid_tuner_instance_list) { \
-               if (((i2cadap) && (state->i2c_props.adap)) &&           \
-                   ((i2c_adapter_id(state->i2c_props.adap) ==          \
-                     i2c_adapter_id(i2cadap)) &&                       \
-                    (i2caddr == state->i2c_props.addr))) {             \
-                       __tuner_info(state->i2c_props,                  \
-                                    "attaching existing instance\n");  \
-                       state->i2c_props.count++;                       \
-                       __ret = state->i2c_props.count;                 \
-                       break;                                          \
-               }                                                       \
-       }                                                               \
-       if (0 == __ret) {                                               \
-               state = kzalloc(sizeof(type), GFP_KERNEL);              \
-               if (NULL == state)                                      \
-                       goto __fail;                                    \
-               state->i2c_props.addr = i2caddr;                        \
-               state->i2c_props.adap = i2cadap;                        \
-               state->i2c_props.name = devname;                        \
-               __tuner_info(state->i2c_props,                          \
-                            "creating new instance\n");                \
-               list_add_tail(&state->hybrid_tuner_instance_list, &list);\
-               state->i2c_props.count++;                               \
-               __ret = state->i2c_props.count;                         \
-       }                                                               \
-__fail:                                                                        \
-       __ret;                                                          \
-})
-
-#define hybrid_tuner_release_state(state)                              \
-({                                                                     \
-       int __ret;                                                      \
-       state->i2c_props.count--;                                       \
-       __ret = state->i2c_props.count;                                 \
-       if (!state->i2c_props.count) {                                  \
-               __tuner_info(state->i2c_props, "destroying instance\n");\
-               list_del(&state->hybrid_tuner_instance_list);           \
-               kfree(state);                                           \
-       }                                                               \
-       __ret;                                                          \
-})
-
-#define hybrid_tuner_report_instance_count(state)                      \
-({                                                                     \
-       int __ret = 0;                                                  \
-       if (state)                                                      \
-               __ret = state->i2c_props.count;                         \
-       __ret;                                                          \
-})
-
-#endif /* __TUNER_I2C_H__ */
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c
deleted file mode 100644 (file)
index 39e7e58..0000000
+++ /dev/null
@@ -1,1155 +0,0 @@
-/*
- * i2c tv tuner chip device driver
- * controls all those simple 4-control-bytes style tuners.
- *
- * This "tuner-simple" module was split apart from the original "tuner" module.
- */
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <media/tuner.h>
-#include <media/v4l2-common.h>
-#include <media/tuner-types.h>
-#include "tuner-i2c.h"
-#include "tuner-simple.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable verbose debug messages");
-
-#define TUNER_SIMPLE_MAX 64
-static unsigned int simple_devcount;
-
-static int offset;
-module_param(offset, int, 0664);
-MODULE_PARM_DESC(offset, "Allows to specify an offset for tuner");
-
-static unsigned int atv_input[TUNER_SIMPLE_MAX] = \
-                       { [0 ... (TUNER_SIMPLE_MAX-1)] = 0 };
-static unsigned int dtv_input[TUNER_SIMPLE_MAX] = \
-                       { [0 ... (TUNER_SIMPLE_MAX-1)] = 0 };
-module_param_array(atv_input, int, NULL, 0644);
-module_param_array(dtv_input, int, NULL, 0644);
-MODULE_PARM_DESC(atv_input, "specify atv rf input, 0 for autoselect");
-MODULE_PARM_DESC(dtv_input, "specify dtv rf input, 0 for autoselect");
-
-/* ---------------------------------------------------------------------- */
-
-/* tv standard selection for Temic 4046 FM5
-   this value takes the low bits of control byte 2
-   from datasheet Rev.01, Feb.00
-     standard     BG      I       L       L2      D
-     picture IF   38.9    38.9    38.9    33.95   38.9
-     sound 1      33.4    32.9    32.4    40.45   32.4
-     sound 2      33.16
-     NICAM        33.05   32.348  33.05           33.05
- */
-#define TEMIC_SET_PAL_I         0x05
-#define TEMIC_SET_PAL_DK        0x09
-#define TEMIC_SET_PAL_L         0x0a /* SECAM ? */
-#define TEMIC_SET_PAL_L2        0x0b /* change IF ! */
-#define TEMIC_SET_PAL_BG        0x0c
-
-/* tv tuner system standard selection for Philips FQ1216ME
-   this value takes the low bits of control byte 2
-   from datasheet "1999 Nov 16" (supersedes "1999 Mar 23")
-     standard          BG      DK      I       L       L`
-     picture carrier   38.90   38.90   38.90   38.90   33.95
-     colour            34.47   34.47   34.47   34.47   38.38
-     sound 1           33.40   32.40   32.90   32.40   40.45
-     sound 2           33.16   -       -       -       -
-     NICAM             33.05   33.05   32.35   33.05   39.80
- */
-#define PHILIPS_SET_PAL_I      0x01 /* Bit 2 always zero !*/
-#define PHILIPS_SET_PAL_BGDK   0x09
-#define PHILIPS_SET_PAL_L2     0x0a
-#define PHILIPS_SET_PAL_L      0x0b
-
-/* system switching for Philips FI1216MF MK2
-   from datasheet "1996 Jul 09",
-    standard         BG     L      L'
-    picture carrier  38.90  38.90  33.95
-    colour          34.47  34.37  38.38
-    sound 1          33.40  32.40  40.45
-    sound 2          33.16  -      -
-    NICAM            33.05  33.05  39.80
- */
-#define PHILIPS_MF_SET_STD_BG  0x01 /* Bit 2 must be zero, Bit 3 is system output */
-#define PHILIPS_MF_SET_STD_L   0x03 /* Used on Secam France */
-#define PHILIPS_MF_SET_STD_LC  0x02 /* Used on SECAM L' */
-
-/* Control byte */
-
-#define TUNER_RATIO_MASK        0x06 /* Bit cb1:cb2 */
-#define TUNER_RATIO_SELECT_50   0x00
-#define TUNER_RATIO_SELECT_32   0x02
-#define TUNER_RATIO_SELECT_166  0x04
-#define TUNER_RATIO_SELECT_62   0x06
-
-#define TUNER_CHARGE_PUMP       0x40  /* Bit cb6 */
-
-/* Status byte */
-
-#define TUNER_POR        0x80
-#define TUNER_FL          0x40
-#define TUNER_MODE        0x38
-#define TUNER_AFC         0x07
-#define TUNER_SIGNAL      0x07
-#define TUNER_STEREO      0x10
-
-#define TUNER_PLL_LOCKED   0x40
-#define TUNER_STEREO_MK3   0x04
-
-static DEFINE_MUTEX(tuner_simple_list_mutex);
-static LIST_HEAD(hybrid_tuner_instance_list);
-
-struct tuner_simple_priv {
-       unsigned int nr;
-       u16 last_div;
-
-       struct tuner_i2c_props i2c_props;
-       struct list_head hybrid_tuner_instance_list;
-
-       unsigned int type;
-       struct tunertype *tun;
-
-       u32 frequency;
-       u32 bandwidth;
-};
-
-/* ---------------------------------------------------------------------- */
-
-static int tuner_read_status(struct dvb_frontend *fe)
-{
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-       unsigned char byte;
-
-       if (1 != tuner_i2c_xfer_recv(&priv->i2c_props, &byte, 1))
-               return 0;
-
-       return byte;
-}
-
-static inline int tuner_signal(const int status)
-{
-       return (status & TUNER_SIGNAL) << 13;
-}
-
-static inline int tuner_stereo(const int type, const int status)
-{
-       switch (type) {
-       case TUNER_PHILIPS_FM1216ME_MK3:
-       case TUNER_PHILIPS_FM1236_MK3:
-       case TUNER_PHILIPS_FM1256_IH3:
-       case TUNER_LG_NTSC_TAPE:
-       case TUNER_TCL_MF02GIP_5N:
-               return ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
-       case TUNER_PHILIPS_FM1216MK5:
-               return status | TUNER_STEREO;
-       default:
-               return status & TUNER_STEREO;
-       }
-}
-
-static inline int tuner_islocked(const int status)
-{
-       return (status & TUNER_FL);
-}
-
-static inline int tuner_afcstatus(const int status)
-{
-       return (status & TUNER_AFC) - 2;
-}
-
-
-static int simple_get_status(struct dvb_frontend *fe, u32 *status)
-{
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-       int tuner_status;
-
-       if (priv->i2c_props.adap == NULL)
-               return -EINVAL;
-
-       tuner_status = tuner_read_status(fe);
-
-       *status = 0;
-
-       if (tuner_islocked(tuner_status))
-               *status = TUNER_STATUS_LOCKED;
-       if (tuner_stereo(priv->type, tuner_status))
-               *status |= TUNER_STATUS_STEREO;
-
-       tuner_dbg("AFC Status: %d\n", tuner_afcstatus(tuner_status));
-
-       return 0;
-}
-
-static int simple_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
-{
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-       int signal;
-
-       if (priv->i2c_props.adap == NULL)
-               return -EINVAL;
-
-       signal = tuner_signal(tuner_read_status(fe));
-
-       *strength = signal;
-
-       tuner_dbg("Signal strength: %d\n", signal);
-
-       return 0;
-}
-
-/* ---------------------------------------------------------------------- */
-
-static inline char *tuner_param_name(enum param_type type)
-{
-       char *name;
-
-       switch (type) {
-       case TUNER_PARAM_TYPE_RADIO:
-               name = "radio";
-               break;
-       case TUNER_PARAM_TYPE_PAL:
-               name = "pal";
-               break;
-       case TUNER_PARAM_TYPE_SECAM:
-               name = "secam";
-               break;
-       case TUNER_PARAM_TYPE_NTSC:
-               name = "ntsc";
-               break;
-       case TUNER_PARAM_TYPE_DIGITAL:
-               name = "digital";
-               break;
-       default:
-               name = "unknown";
-               break;
-       }
-       return name;
-}
-
-static struct tuner_params *simple_tuner_params(struct dvb_frontend *fe,
-                                               enum param_type desired_type)
-{
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-       struct tunertype *tun = priv->tun;
-       int i;
-
-       for (i = 0; i < tun->count; i++)
-               if (desired_type == tun->params[i].type)
-                       break;
-
-       /* use default tuner params if desired_type not available */
-       if (i == tun->count) {
-               tuner_dbg("desired params (%s) undefined for tuner %d\n",
-                         tuner_param_name(desired_type), priv->type);
-               i = 0;
-       }
-
-       tuner_dbg("using tuner params #%d (%s)\n", i,
-                 tuner_param_name(tun->params[i].type));
-
-       return &tun->params[i];
-}
-
-static int simple_config_lookup(struct dvb_frontend *fe,
-                               struct tuner_params *t_params,
-                               unsigned *frequency, u8 *config, u8 *cb)
-{
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-       int i;
-
-       for (i = 0; i < t_params->count; i++) {
-               if (*frequency > t_params->ranges[i].limit)
-                       continue;
-               break;
-       }
-       if (i == t_params->count) {
-               tuner_dbg("frequency out of range (%d > %d)\n",
-                         *frequency, t_params->ranges[i - 1].limit);
-               *frequency = t_params->ranges[--i].limit;
-       }
-       *config = t_params->ranges[i].config;
-       *cb     = t_params->ranges[i].cb;
-
-       tuner_dbg("freq = %d.%02d (%d), range = %d, "
-                 "config = 0x%02x, cb = 0x%02x\n",
-                 *frequency / 16, *frequency % 16 * 100 / 16, *frequency,
-                 i, *config, *cb);
-
-       return i;
-}
-
-/* ---------------------------------------------------------------------- */
-
-static void simple_set_rf_input(struct dvb_frontend *fe,
-                               u8 *config, u8 *cb, unsigned int rf)
-{
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-
-       switch (priv->type) {
-       case TUNER_PHILIPS_TUV1236D:
-               switch (rf) {
-               case 1:
-                       *cb |= 0x08;
-                       break;
-               default:
-                       *cb &= ~0x08;
-                       break;
-               }
-               break;
-       case TUNER_PHILIPS_FCV1236D:
-               switch (rf) {
-               case 1:
-                       *cb |= 0x01;
-                       break;
-               default:
-                       *cb &= ~0x01;
-                       break;
-               }
-               break;
-       default:
-               break;
-       }
-}
-
-static int simple_std_setup(struct dvb_frontend *fe,
-                           struct analog_parameters *params,
-                           u8 *config, u8 *cb)
-{
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-       int rc;
-
-       /* tv norm specific stuff for multi-norm tuners */
-       switch (priv->type) {
-       case TUNER_PHILIPS_SECAM: /* FI1216MF */
-               /* 0x01 -> ??? no change ??? */
-               /* 0x02 -> PAL BDGHI / SECAM L */
-               /* 0x04 -> ??? PAL others / SECAM others ??? */
-               *cb &= ~0x03;
-               if (params->std & V4L2_STD_SECAM_L)
-                       /* also valid for V4L2_STD_SECAM */
-                       *cb |= PHILIPS_MF_SET_STD_L;
-               else if (params->std & V4L2_STD_SECAM_LC)
-                       *cb |= PHILIPS_MF_SET_STD_LC;
-               else /* V4L2_STD_B|V4L2_STD_GH */
-                       *cb |= PHILIPS_MF_SET_STD_BG;
-               break;
-
-       case TUNER_TEMIC_4046FM5:
-               *cb &= ~0x0f;
-
-               if (params->std & V4L2_STD_PAL_BG) {
-                       *cb |= TEMIC_SET_PAL_BG;
-
-               } else if (params->std & V4L2_STD_PAL_I) {
-                       *cb |= TEMIC_SET_PAL_I;
-
-               } else if (params->std & V4L2_STD_PAL_DK) {
-                       *cb |= TEMIC_SET_PAL_DK;
-
-               } else if (params->std & V4L2_STD_SECAM_L) {
-                       *cb |= TEMIC_SET_PAL_L;
-
-               }
-               break;
-
-       case TUNER_PHILIPS_FQ1216ME:
-               *cb &= ~0x0f;
-
-               if (params->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) {
-                       *cb |= PHILIPS_SET_PAL_BGDK;
-
-               } else if (params->std & V4L2_STD_PAL_I) {
-                       *cb |= PHILIPS_SET_PAL_I;
-
-               } else if (params->std & V4L2_STD_SECAM_L) {
-                       *cb |= PHILIPS_SET_PAL_L;
-
-               }
-               break;
-
-       case TUNER_PHILIPS_FCV1236D:
-               /* 0x00 -> ATSC antenna input 1 */
-               /* 0x01 -> ATSC antenna input 2 */
-               /* 0x02 -> NTSC antenna input 1 */
-               /* 0x03 -> NTSC antenna input 2 */
-               *cb &= ~0x03;
-               if (!(params->std & V4L2_STD_ATSC))
-                       *cb |= 2;
-               break;
-
-       case TUNER_MICROTUNE_4042FI5:
-               /* Set the charge pump for fast tuning */
-               *config |= TUNER_CHARGE_PUMP;
-               break;
-
-       case TUNER_PHILIPS_TUV1236D:
-       {
-               struct tuner_i2c_props i2c = priv->i2c_props;
-               /* 0x40 -> ATSC antenna input 1 */
-               /* 0x48 -> ATSC antenna input 2 */
-               /* 0x00 -> NTSC antenna input 1 */
-               /* 0x08 -> NTSC antenna input 2 */
-               u8 buffer[4] = { 0x14, 0x00, 0x17, 0x00};
-               *cb &= ~0x40;
-               if (params->std & V4L2_STD_ATSC) {
-                       *cb |= 0x40;
-                       buffer[1] = 0x04;
-               }
-               /* set to the correct mode (analog or digital) */
-               i2c.addr = 0x0a;
-               rc = tuner_i2c_xfer_send(&i2c, &buffer[0], 2);
-               if (2 != rc)
-                       tuner_warn("i2c i/o error: rc == %d "
-                                  "(should be 2)\n", rc);
-               rc = tuner_i2c_xfer_send(&i2c, &buffer[2], 2);
-               if (2 != rc)
-                       tuner_warn("i2c i/o error: rc == %d "
-                                  "(should be 2)\n", rc);
-               break;
-       }
-       }
-       if (atv_input[priv->nr])
-               simple_set_rf_input(fe, config, cb, atv_input[priv->nr]);
-
-       return 0;
-}
-
-static int simple_set_aux_byte(struct dvb_frontend *fe, u8 config, u8 aux)
-{
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-       int rc;
-       u8 buffer[2];
-
-       buffer[0] = (config & ~0x38) | 0x18;
-       buffer[1] = aux;
-
-       tuner_dbg("setting aux byte: 0x%02x 0x%02x\n", buffer[0], buffer[1]);
-
-       rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2);
-       if (2 != rc)
-               tuner_warn("i2c i/o error: rc == %d (should be 2)\n", rc);
-
-       return rc == 2 ? 0 : rc;
-}
-
-static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer,
-                           u16 div, u8 config, u8 cb)
-{
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-       int rc;
-
-       switch (priv->type) {
-       case TUNER_LG_TDVS_H06XF:
-               simple_set_aux_byte(fe, config, 0x20);
-               break;
-       case TUNER_PHILIPS_FQ1216LME_MK3:
-               simple_set_aux_byte(fe, config, 0x60); /* External AGC */
-               break;
-       case TUNER_MICROTUNE_4042FI5:
-       {
-               /* FIXME - this may also work for other tuners */
-               unsigned long timeout = jiffies + msecs_to_jiffies(1);
-               u8 status_byte = 0;
-
-               /* Wait until the PLL locks */
-               for (;;) {
-                       if (time_after(jiffies, timeout))
-                               return 0;
-                       rc = tuner_i2c_xfer_recv(&priv->i2c_props,
-                                                &status_byte, 1);
-                       if (1 != rc) {
-                               tuner_warn("i2c i/o read error: rc == %d "
-                                          "(should be 1)\n", rc);
-                               break;
-                       }
-                       if (status_byte & TUNER_PLL_LOCKED)
-                               break;
-                       udelay(10);
-               }
-
-               /* Set the charge pump for optimized phase noise figure */
-               config &= ~TUNER_CHARGE_PUMP;
-               buffer[0] = (div>>8) & 0x7f;
-               buffer[1] = div      & 0xff;
-               buffer[2] = config;
-               buffer[3] = cb;
-               tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
-                         buffer[0], buffer[1], buffer[2], buffer[3]);
-
-               rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4);
-               if (4 != rc)
-                       tuner_warn("i2c i/o error: rc == %d "
-                                  "(should be 4)\n", rc);
-               break;
-       }
-       }
-
-       return 0;
-}
-
-static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer)
-{
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-
-       switch (priv->type) {
-       case TUNER_TENA_9533_DI:
-       case TUNER_YMEC_TVF_5533MF:
-               tuner_dbg("This tuner doesn't have FM. "
-                         "Most cards have a TEA5767 for FM\n");
-               return 0;
-       case TUNER_PHILIPS_FM1216ME_MK3:
-       case TUNER_PHILIPS_FM1236_MK3:
-       case TUNER_PHILIPS_FMD1216ME_MK3:
-       case TUNER_PHILIPS_FMD1216MEX_MK3:
-       case TUNER_LG_NTSC_TAPE:
-       case TUNER_PHILIPS_FM1256_IH3:
-       case TUNER_TCL_MF02GIP_5N:
-               buffer[3] = 0x19;
-               break;
-       case TUNER_PHILIPS_FM1216MK5:
-               buffer[2] = 0x88;
-               buffer[3] = 0x09;
-               break;
-       case TUNER_TNF_5335MF:
-               buffer[3] = 0x11;
-               break;
-       case TUNER_LG_PAL_FM:
-               buffer[3] = 0xa5;
-               break;
-       case TUNER_THOMSON_DTT761X:
-               buffer[3] = 0x39;
-               break;
-       case TUNER_PHILIPS_FQ1216LME_MK3:
-       case TUNER_PHILIPS_FQ1236_MK5:
-               tuner_err("This tuner doesn't have FM\n");
-               /* Set the low band for sanity, since it covers 88-108 MHz */
-               buffer[3] = 0x01;
-               break;
-       case TUNER_MICROTUNE_4049FM5:
-       default:
-               buffer[3] = 0xa4;
-               break;
-       }
-
-       return 0;
-}
-
-/* ---------------------------------------------------------------------- */
-
-static int simple_set_tv_freq(struct dvb_frontend *fe,
-                             struct analog_parameters *params)
-{
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-       u8 config, cb;
-       u16 div;
-       u8 buffer[4];
-       int rc, IFPCoff, i;
-       enum param_type desired_type;
-       struct tuner_params *t_params;
-
-       /* IFPCoff = Video Intermediate Frequency - Vif:
-               940  =16*58.75  NTSC/J (Japan)
-               732  =16*45.75  M/N STD
-               704  =16*44     ATSC (at DVB code)
-               632  =16*39.50  I U.K.
-               622.4=16*38.90  B/G D/K I, L STD
-               592  =16*37.00  D China
-               590  =16.36.875 B Australia
-               543.2=16*33.95  L' STD
-               171.2=16*10.70  FM Radio (at set_radio_freq)
-       */
-
-       if (params->std == V4L2_STD_NTSC_M_JP) {
-               IFPCoff      = 940;
-               desired_type = TUNER_PARAM_TYPE_NTSC;
-       } else if ((params->std & V4L2_STD_MN) &&
-                 !(params->std & ~V4L2_STD_MN)) {
-               IFPCoff      = 732;
-               desired_type = TUNER_PARAM_TYPE_NTSC;
-       } else if (params->std == V4L2_STD_SECAM_LC) {
-               IFPCoff      = 543;
-               desired_type = TUNER_PARAM_TYPE_SECAM;
-       } else {
-               IFPCoff      = 623;
-               desired_type = TUNER_PARAM_TYPE_PAL;
-       }
-
-       t_params = simple_tuner_params(fe, desired_type);
-
-       i = simple_config_lookup(fe, t_params, &params->frequency,
-                                &config, &cb);
-
-       div = params->frequency + IFPCoff + offset;
-
-       tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, "
-                 "Offset=%d.%02d MHz, div=%0d\n",
-                 params->frequency / 16, params->frequency % 16 * 100 / 16,
-                 IFPCoff / 16, IFPCoff % 16 * 100 / 16,
-                 offset / 16, offset % 16 * 100 / 16, div);
-
-       /* tv norm specific stuff for multi-norm tuners */
-       simple_std_setup(fe, params, &config, &cb);
-
-       if (t_params->cb_first_if_lower_freq && div < priv->last_div) {
-               buffer[0] = config;
-               buffer[1] = cb;
-               buffer[2] = (div>>8) & 0x7f;
-               buffer[3] = div      & 0xff;
-       } else {
-               buffer[0] = (div>>8) & 0x7f;
-               buffer[1] = div      & 0xff;
-               buffer[2] = config;
-               buffer[3] = cb;
-       }
-       priv->last_div = div;
-       if (t_params->has_tda9887) {
-               struct v4l2_priv_tun_config tda9887_cfg;
-               int tda_config = 0;
-               int is_secam_l = (params->std & (V4L2_STD_SECAM_L |
-                                                V4L2_STD_SECAM_LC)) &&
-                       !(params->std & ~(V4L2_STD_SECAM_L |
-                                         V4L2_STD_SECAM_LC));
-
-               tda9887_cfg.tuner = TUNER_TDA9887;
-               tda9887_cfg.priv  = &tda_config;
-
-               if (params->std == V4L2_STD_SECAM_LC) {
-                       if (t_params->port1_active ^ t_params->port1_invert_for_secam_lc)
-                               tda_config |= TDA9887_PORT1_ACTIVE;
-                       if (t_params->port2_active ^ t_params->port2_invert_for_secam_lc)
-                               tda_config |= TDA9887_PORT2_ACTIVE;
-               } else {
-                       if (t_params->port1_active)
-                               tda_config |= TDA9887_PORT1_ACTIVE;
-                       if (t_params->port2_active)
-                               tda_config |= TDA9887_PORT2_ACTIVE;
-               }
-               if (t_params->intercarrier_mode)
-                       tda_config |= TDA9887_INTERCARRIER;
-               if (is_secam_l) {
-                       if (i == 0 && t_params->default_top_secam_low)
-                               tda_config |= TDA9887_TOP(t_params->default_top_secam_low);
-                       else if (i == 1 && t_params->default_top_secam_mid)
-                               tda_config |= TDA9887_TOP(t_params->default_top_secam_mid);
-                       else if (t_params->default_top_secam_high)
-                               tda_config |= TDA9887_TOP(t_params->default_top_secam_high);
-               } else {
-                       if (i == 0 && t_params->default_top_low)
-                               tda_config |= TDA9887_TOP(t_params->default_top_low);
-                       else if (i == 1 && t_params->default_top_mid)
-                               tda_config |= TDA9887_TOP(t_params->default_top_mid);
-                       else if (t_params->default_top_high)
-                               tda_config |= TDA9887_TOP(t_params->default_top_high);
-               }
-               if (t_params->default_pll_gating_18)
-                       tda_config |= TDA9887_GATING_18;
-               i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG,
-                                   &tda9887_cfg);
-       }
-       tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
-                 buffer[0], buffer[1], buffer[2], buffer[3]);
-
-       rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4);
-       if (4 != rc)
-               tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc);
-
-       simple_post_tune(fe, &buffer[0], div, config, cb);
-
-       return 0;
-}
-
-static int simple_set_radio_freq(struct dvb_frontend *fe,
-                                struct analog_parameters *params)
-{
-       struct tunertype *tun;
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-       u8 buffer[4];
-       u16 div;
-       int rc, j;
-       struct tuner_params *t_params;
-       unsigned int freq = params->frequency;
-
-       tun = priv->tun;
-
-       for (j = tun->count-1; j > 0; j--)
-               if (tun->params[j].type == TUNER_PARAM_TYPE_RADIO)
-                       break;
-       /* default t_params (j=0) will be used if desired type wasn't found */
-       t_params = &tun->params[j];
-
-       /* Select Radio 1st IF used */
-       switch (t_params->radio_if) {
-       case 0: /* 10.7 MHz */
-               freq += (unsigned int)(10.7*16000);
-               break;
-       case 1: /* 33.3 MHz */
-               freq += (unsigned int)(33.3*16000);
-               break;
-       case 2: /* 41.3 MHz */
-               freq += (unsigned int)(41.3*16000);
-               break;
-       default:
-               tuner_warn("Unsupported radio_if value %d\n",
-                          t_params->radio_if);
-               return 0;
-       }
-
-       buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) |
-                   TUNER_RATIO_SELECT_50; /* 50 kHz step */
-
-       /* Bandswitch byte */
-       simple_radio_bandswitch(fe, &buffer[0]);
-
-       /* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps
-          freq * (1 Mhz / 16000 V4L steps) * (20 PLL steps / 1 MHz) =
-          freq * (1/800) */
-       div = (freq + 400) / 800;
-
-       if (t_params->cb_first_if_lower_freq && div < priv->last_div) {
-               buffer[0] = buffer[2];
-               buffer[1] = buffer[3];
-               buffer[2] = (div>>8) & 0x7f;
-               buffer[3] = div      & 0xff;
-       } else {
-               buffer[0] = (div>>8) & 0x7f;
-               buffer[1] = div      & 0xff;
-       }
-
-       tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n",
-              buffer[0], buffer[1], buffer[2], buffer[3]);
-       priv->last_div = div;
-
-       if (t_params->has_tda9887) {
-               int config = 0;
-               struct v4l2_priv_tun_config tda9887_cfg;
-
-               tda9887_cfg.tuner = TUNER_TDA9887;
-               tda9887_cfg.priv = &config;
-
-               if (t_params->port1_active &&
-                   !t_params->port1_fm_high_sensitivity)
-                       config |= TDA9887_PORT1_ACTIVE;
-               if (t_params->port2_active &&
-                   !t_params->port2_fm_high_sensitivity)
-                       config |= TDA9887_PORT2_ACTIVE;
-               if (t_params->intercarrier_mode)
-                       config |= TDA9887_INTERCARRIER;
-/*             if (t_params->port1_set_for_fm_mono)
-                       config &= ~TDA9887_PORT1_ACTIVE;*/
-               if (t_params->fm_gain_normal)
-                       config |= TDA9887_GAIN_NORMAL;
-               if (t_params->radio_if == 2)
-                       config |= TDA9887_RIF_41_3;
-               i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG,
-                                   &tda9887_cfg);
-       }
-       rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4);
-       if (4 != rc)
-               tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc);
-
-       /* Write AUX byte */
-       switch (priv->type) {
-       case TUNER_PHILIPS_FM1216ME_MK3:
-               buffer[2] = 0x98;
-               buffer[3] = 0x20; /* set TOP AGC */
-               rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4);
-               if (4 != rc)
-                       tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc);
-               break;
-       }
-
-       return 0;
-}
-
-static int simple_set_params(struct dvb_frontend *fe,
-                            struct analog_parameters *params)
-{
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-       int ret = -EINVAL;
-
-       if (priv->i2c_props.adap == NULL)
-               return -EINVAL;
-
-       switch (params->mode) {
-       case V4L2_TUNER_RADIO:
-               ret = simple_set_radio_freq(fe, params);
-               priv->frequency = params->frequency * 125 / 2;
-               break;
-       case V4L2_TUNER_ANALOG_TV:
-       case V4L2_TUNER_DIGITAL_TV:
-               ret = simple_set_tv_freq(fe, params);
-               priv->frequency = params->frequency * 62500;
-               break;
-       }
-       priv->bandwidth = 0;
-
-       return ret;
-}
-
-static void simple_set_dvb(struct dvb_frontend *fe, u8 *buf,
-                          const u32 delsys,
-                          const u32 frequency,
-                          const u32 bandwidth)
-{
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-
-       switch (priv->type) {
-       case TUNER_PHILIPS_FMD1216ME_MK3:
-       case TUNER_PHILIPS_FMD1216MEX_MK3:
-               if (bandwidth == 8000000 &&
-                   frequency >= 158870000)
-                       buf[3] |= 0x08;
-               break;
-       case TUNER_PHILIPS_TD1316:
-               /* determine band */
-               buf[3] |= (frequency < 161000000) ? 1 :
-                         (frequency < 444000000) ? 2 : 4;
-
-               /* setup PLL filter */
-               if (bandwidth == 8000000)
-                       buf[3] |= 1 << 3;
-               break;
-       case TUNER_PHILIPS_TUV1236D:
-       case TUNER_PHILIPS_FCV1236D:
-       {
-               unsigned int new_rf;
-
-               if (dtv_input[priv->nr])
-                       new_rf = dtv_input[priv->nr];
-               else
-                       switch (delsys) {
-                       case SYS_DVBC_ANNEX_B:
-                               new_rf = 1;
-                               break;
-                       case SYS_ATSC:
-                       default:
-                               new_rf = 0;
-                               break;
-                       }
-               simple_set_rf_input(fe, &buf[2], &buf[3], new_rf);
-               break;
-       }
-       default:
-               break;
-       }
-}
-
-static u32 simple_dvb_configure(struct dvb_frontend *fe, u8 *buf,
-                               const u32 delsys,
-                               const u32 freq,
-                               const u32 bw)
-{
-       /* This function returns the tuned frequency on success, 0 on error */
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-       struct tunertype *tun = priv->tun;
-       static struct tuner_params *t_params;
-       u8 config, cb;
-       u32 div;
-       int ret;
-       u32 frequency = freq / 62500;
-
-       if (!tun->stepsize) {
-               /* tuner-core was loaded before the digital tuner was
-                * configured and somehow picked the wrong tuner type */
-               tuner_err("attempt to treat tuner %d (%s) as digital tuner "
-                         "without stepsize defined.\n",
-                         priv->type, priv->tun->name);
-               return 0; /* failure */
-       }
-
-       t_params = simple_tuner_params(fe, TUNER_PARAM_TYPE_DIGITAL);
-       ret = simple_config_lookup(fe, t_params, &frequency, &config, &cb);
-       if (ret < 0)
-               return 0; /* failure */
-
-       div = ((frequency + t_params->iffreq) * 62500 + offset +
-              tun->stepsize/2) / tun->stepsize;
-
-       buf[0] = div >> 8;
-       buf[1] = div & 0xff;
-       buf[2] = config;
-       buf[3] = cb;
-
-       simple_set_dvb(fe, buf, delsys, freq, bw);
-
-       tuner_dbg("%s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n",
-                 tun->name, div, buf[0], buf[1], buf[2], buf[3]);
-
-       /* calculate the frequency we set it to */
-       return (div * tun->stepsize) - t_params->iffreq;
-}
-
-static int simple_dvb_calc_regs(struct dvb_frontend *fe,
-                               u8 *buf, int buf_len)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u32 delsys = c->delivery_system;
-       u32 bw = c->bandwidth_hz;
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-       u32 frequency;
-
-       if (buf_len < 5)
-               return -EINVAL;
-
-       frequency = simple_dvb_configure(fe, buf+1, delsys, c->frequency, bw);
-       if (frequency == 0)
-               return -EINVAL;
-
-       buf[0] = priv->i2c_props.addr;
-
-       priv->frequency = frequency;
-       priv->bandwidth = c->bandwidth_hz;
-
-       return 5;
-}
-
-static int simple_dvb_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u32 delsys = c->delivery_system;
-       u32 bw = c->bandwidth_hz;
-       u32 freq = c->frequency;
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-       u32 frequency;
-       u32 prev_freq, prev_bw;
-       int ret;
-       u8 buf[5];
-
-       if (priv->i2c_props.adap == NULL)
-               return -EINVAL;
-
-       prev_freq = priv->frequency;
-       prev_bw   = priv->bandwidth;
-
-       frequency = simple_dvb_configure(fe, buf+1, delsys, freq, bw);
-       if (frequency == 0)
-               return -EINVAL;
-
-       buf[0] = priv->i2c_props.addr;
-
-       priv->frequency = frequency;
-       priv->bandwidth = bw;
-
-       /* put analog demod in standby when tuning digital */
-       if (fe->ops.analog_ops.standby)
-               fe->ops.analog_ops.standby(fe);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1);
-
-       /* buf[0] contains the i2c address, but *
-        * we already have it in i2c_props.addr */
-       ret = tuner_i2c_xfer_send(&priv->i2c_props, buf+1, 4);
-       if (ret != 4)
-               goto fail;
-
-       return 0;
-fail:
-       /* calc_regs sets frequency and bandwidth. if we failed, unset them */
-       priv->frequency = prev_freq;
-       priv->bandwidth = prev_bw;
-
-       return ret;
-}
-
-static int simple_init(struct dvb_frontend *fe)
-{
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-
-       if (priv->i2c_props.adap == NULL)
-               return -EINVAL;
-
-       if (priv->tun->initdata) {
-               int ret;
-
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-
-               ret = tuner_i2c_xfer_send(&priv->i2c_props,
-                                         priv->tun->initdata + 1,
-                                         priv->tun->initdata[0]);
-               if (ret != priv->tun->initdata[0])
-                       return ret;
-       }
-
-       return 0;
-}
-
-static int simple_sleep(struct dvb_frontend *fe)
-{
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-
-       if (priv->i2c_props.adap == NULL)
-               return -EINVAL;
-
-       if (priv->tun->sleepdata) {
-               int ret;
-
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-
-               ret = tuner_i2c_xfer_send(&priv->i2c_props,
-                                         priv->tun->sleepdata + 1,
-                                         priv->tun->sleepdata[0]);
-               if (ret != priv->tun->sleepdata[0])
-                       return ret;
-       }
-
-       return 0;
-}
-
-static int simple_release(struct dvb_frontend *fe)
-{
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-
-       mutex_lock(&tuner_simple_list_mutex);
-
-       if (priv)
-               hybrid_tuner_release_state(priv);
-
-       mutex_unlock(&tuner_simple_list_mutex);
-
-       fe->tuner_priv = NULL;
-
-       return 0;
-}
-
-static int simple_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-       *frequency = priv->frequency;
-       return 0;
-}
-
-static int simple_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct tuner_simple_priv *priv = fe->tuner_priv;
-       *bandwidth = priv->bandwidth;
-       return 0;
-}
-
-static struct dvb_tuner_ops simple_tuner_ops = {
-       .init              = simple_init,
-       .sleep             = simple_sleep,
-       .set_analog_params = simple_set_params,
-       .set_params        = simple_dvb_set_params,
-       .calc_regs         = simple_dvb_calc_regs,
-       .release           = simple_release,
-       .get_frequency     = simple_get_frequency,
-       .get_bandwidth     = simple_get_bandwidth,
-       .get_status        = simple_get_status,
-       .get_rf_strength   = simple_get_rf_strength,
-};
-
-struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
-                                        struct i2c_adapter *i2c_adap,
-                                        u8 i2c_addr,
-                                        unsigned int type)
-{
-       struct tuner_simple_priv *priv = NULL;
-       int instance;
-
-       if (type >= tuner_count) {
-               printk(KERN_WARNING "%s: invalid tuner type: %d (max: %d)\n",
-                      __func__, type, tuner_count-1);
-               return NULL;
-       }
-
-       /* If i2c_adap is set, check that the tuner is at the correct address.
-        * Otherwise, if i2c_adap is NULL, the tuner will be programmed directly
-        * by the digital demod via calc_regs.
-        */
-       if (i2c_adap != NULL) {
-               u8 b[1];
-               struct i2c_msg msg = {
-                       .addr = i2c_addr, .flags = I2C_M_RD,
-                       .buf = b, .len = 1,
-               };
-
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 1);
-
-               if (1 != i2c_transfer(i2c_adap, &msg, 1))
-                       printk(KERN_WARNING "tuner-simple %d-%04x: "
-                              "unable to probe %s, proceeding anyway.",
-                              i2c_adapter_id(i2c_adap), i2c_addr,
-                              tuners[type].name);
-
-               if (fe->ops.i2c_gate_ctrl)
-                       fe->ops.i2c_gate_ctrl(fe, 0);
-       }
-
-       mutex_lock(&tuner_simple_list_mutex);
-
-       instance = hybrid_tuner_request_state(struct tuner_simple_priv, priv,
-                                             hybrid_tuner_instance_list,
-                                             i2c_adap, i2c_addr,
-                                             "tuner-simple");
-       switch (instance) {
-       case 0:
-               mutex_unlock(&tuner_simple_list_mutex);
-               return NULL;
-       case 1:
-               fe->tuner_priv = priv;
-
-               priv->type = type;
-               priv->tun  = &tuners[type];
-               priv->nr   = simple_devcount++;
-               break;
-       default:
-               fe->tuner_priv = priv;
-               break;
-       }
-
-       mutex_unlock(&tuner_simple_list_mutex);
-
-       memcpy(&fe->ops.tuner_ops, &simple_tuner_ops,
-              sizeof(struct dvb_tuner_ops));
-
-       if (type != priv->type)
-               tuner_warn("couldn't set type to %d. Using %d (%s) instead\n",
-                           type, priv->type, priv->tun->name);
-       else
-               tuner_info("type set to %d (%s)\n",
-                          priv->type, priv->tun->name);
-
-       if ((debug) || ((atv_input[priv->nr] > 0) ||
-                       (dtv_input[priv->nr] > 0))) {
-               if (0 == atv_input[priv->nr])
-                       tuner_info("tuner %d atv rf input will be "
-                                  "autoselected\n", priv->nr);
-               else
-                       tuner_info("tuner %d atv rf input will be "
-                                  "set to input %d (insmod option)\n",
-                                  priv->nr, atv_input[priv->nr]);
-               if (0 == dtv_input[priv->nr])
-                       tuner_info("tuner %d dtv rf input will be "
-                                  "autoselected\n", priv->nr);
-               else
-                       tuner_info("tuner %d dtv rf input will be "
-                                  "set to input %d (insmod option)\n",
-                                  priv->nr, dtv_input[priv->nr]);
-       }
-
-       strlcpy(fe->ops.tuner_ops.info.name, priv->tun->name,
-               sizeof(fe->ops.tuner_ops.info.name));
-
-       return fe;
-}
-EXPORT_SYMBOL_GPL(simple_tuner_attach);
-
-MODULE_DESCRIPTION("Simple 4-control-bytes style tuner driver");
-MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
-MODULE_LICENSE("GPL");
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/common/tuners/tuner-simple.h b/drivers/media/common/tuners/tuner-simple.h
deleted file mode 100644 (file)
index 381fa5d..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-    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 __TUNER_SIMPLE_H__
-#define __TUNER_SIMPLE_H__
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-
-#if defined(CONFIG_MEDIA_TUNER_SIMPLE) || (defined(CONFIG_MEDIA_TUNER_SIMPLE_MODULE) && defined(MODULE))
-extern struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
-                                               struct i2c_adapter *i2c_adap,
-                                               u8 i2c_addr,
-                                               unsigned int type);
-#else
-static inline struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
-                                                      struct i2c_adapter *i2c_adap,
-                                                      u8 i2c_addr,
-                                                      unsigned int type)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif /* __TUNER_SIMPLE_H__ */
diff --git a/drivers/media/common/tuners/tuner-types.c b/drivers/media/common/tuners/tuner-types.c
deleted file mode 100644 (file)
index 2da4440..0000000
+++ /dev/null
@@ -1,1883 +0,0 @@
-/*
- *
- * i2c tv tuner chip device type database.
- *
- */
-
-#include <linux/i2c.h>
-#include <linux/module.h>
-#include <media/tuner.h>
-#include <media/tuner-types.h>
-
-/* ---------------------------------------------------------------------- */
-
-/*
- *     The floats in the tuner struct are computed at compile time
- *     by gcc and cast back to integers. Thus we don't violate the
- *     "no float in kernel" rule.
- *
- *     A tuner_range may be referenced by multiple tuner_params structs.
- *     There are many duplicates in here. Reusing tuner_range structs,
- *     rather than defining new ones for each tuner, will cut down on
- *     memory usage, and is preferred when possible.
- *
- *     Each tuner_params array may contain one or more elements, one
- *     for each video standard.
- *
- *     FIXME: tuner_params struct contains an element, tda988x. We must
- *     set this for all tuners that contain a tda988x chip, and then we
- *     can remove this setting from the various card structs.
- *
- *     FIXME: Right now, all tuners are using the first tuner_params[]
- *     array element for analog mode. In the future, we will be merging
- *     similar tuner definitions together, such that each tuner definition
- *     will have a tuner_params struct for each available video standard.
- *     At that point, the tuner_params[] array element will be chosen
- *     based on the video standard in use.
- */
-
-/* The following was taken from dvb-pll.c: */
-
-/* Set AGC TOP value to 103 dBuV:
- *     0x80 = Control Byte
- *     0x40 = 250 uA charge pump (irrelevant)
- *     0x18 = Aux Byte to follow
- *     0x06 = 64.5 kHz divider (irrelevant)
- *     0x01 = Disable Vt (aka sleep)
- *
- *     0x00 = AGC Time constant 2s Iagc = 300 nA (vs 0x80 = 9 nA)
- *     0x50 = AGC Take over point = 103 dBuV
- */
-static u8 tua603x_agc103[] = { 2, 0x80|0x40|0x18|0x06|0x01, 0x00|0x50 };
-
-/*     0x04 = 166.67 kHz divider
- *
- *     0x80 = AGC Time constant 50ms Iagc = 9 uA
- *     0x20 = AGC Take over point = 112 dBuV
- */
-static u8 tua603x_agc112[] = { 2, 0x80|0x40|0x18|0x04|0x01, 0x80|0x20 };
-
-/* 0-9 */
-/* ------------ TUNER_TEMIC_PAL - TEMIC PAL ------------ */
-
-static struct tuner_range tuner_temic_pal_ranges[] = {
-       { 16 * 140.25 /*MHz*/, 0x8e, 0x02, },
-       { 16 * 463.25 /*MHz*/, 0x8e, 0x04, },
-       { 16 * 999.99        , 0x8e, 0x01, },
-};
-
-static struct tuner_params tuner_temic_pal_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_temic_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_pal_ranges),
-       },
-};
-
-/* ------------ TUNER_PHILIPS_PAL_I - Philips PAL_I ------------ */
-
-static struct tuner_range tuner_philips_pal_i_ranges[] = {
-       { 16 * 140.25 /*MHz*/, 0x8e, 0xa0, },
-       { 16 * 463.25 /*MHz*/, 0x8e, 0x90, },
-       { 16 * 999.99        , 0x8e, 0x30, },
-};
-
-static struct tuner_params tuner_philips_pal_i_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_philips_pal_i_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_pal_i_ranges),
-       },
-};
-
-/* ------------ TUNER_PHILIPS_NTSC - Philips NTSC ------------ */
-
-static struct tuner_range tuner_philips_ntsc_ranges[] = {
-       { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, },
-       { 16 * 451.25 /*MHz*/, 0x8e, 0x90, },
-       { 16 * 999.99        , 0x8e, 0x30, },
-};
-
-static struct tuner_params tuner_philips_ntsc_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_philips_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_ntsc_ranges),
-               .cb_first_if_lower_freq = 1,
-       },
-};
-
-/* ------------ TUNER_PHILIPS_SECAM - Philips SECAM ------------ */
-
-static struct tuner_range tuner_philips_secam_ranges[] = {
-       { 16 * 168.25 /*MHz*/, 0x8e, 0xa7, },
-       { 16 * 447.25 /*MHz*/, 0x8e, 0x97, },
-       { 16 * 999.99        , 0x8e, 0x37, },
-};
-
-static struct tuner_params tuner_philips_secam_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_SECAM,
-               .ranges = tuner_philips_secam_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_secam_ranges),
-               .cb_first_if_lower_freq = 1,
-       },
-};
-
-/* ------------ TUNER_PHILIPS_PAL - Philips PAL ------------ */
-
-static struct tuner_range tuner_philips_pal_ranges[] = {
-       { 16 * 168.25 /*MHz*/, 0x8e, 0xa0, },
-       { 16 * 447.25 /*MHz*/, 0x8e, 0x90, },
-       { 16 * 999.99        , 0x8e, 0x30, },
-};
-
-static struct tuner_params tuner_philips_pal_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_philips_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_pal_ranges),
-               .cb_first_if_lower_freq = 1,
-       },
-};
-
-/* ------------ TUNER_TEMIC_NTSC - TEMIC NTSC ------------ */
-
-static struct tuner_range tuner_temic_ntsc_ranges[] = {
-       { 16 * 157.25 /*MHz*/, 0x8e, 0x02, },
-       { 16 * 463.25 /*MHz*/, 0x8e, 0x04, },
-       { 16 * 999.99        , 0x8e, 0x01, },
-};
-
-static struct tuner_params tuner_temic_ntsc_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_temic_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_ntsc_ranges),
-       },
-};
-
-/* ------------ TUNER_TEMIC_PAL_I - TEMIC PAL_I ------------ */
-
-static struct tuner_range tuner_temic_pal_i_ranges[] = {
-       { 16 * 170.00 /*MHz*/, 0x8e, 0x02, },
-       { 16 * 450.00 /*MHz*/, 0x8e, 0x04, },
-       { 16 * 999.99        , 0x8e, 0x01, },
-};
-
-static struct tuner_params tuner_temic_pal_i_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_temic_pal_i_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_pal_i_ranges),
-       },
-};
-
-/* ------------ TUNER_TEMIC_4036FY5_NTSC - TEMIC NTSC ------------ */
-
-static struct tuner_range tuner_temic_4036fy5_ntsc_ranges[] = {
-       { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, },
-       { 16 * 463.25 /*MHz*/, 0x8e, 0x90, },
-       { 16 * 999.99        , 0x8e, 0x30, },
-};
-
-static struct tuner_params tuner_temic_4036fy5_ntsc_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_temic_4036fy5_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_4036fy5_ntsc_ranges),
-       },
-};
-
-/* ------------ TUNER_ALPS_TSBH1_NTSC - TEMIC NTSC ------------ */
-
-static struct tuner_range tuner_alps_tsb_1_ranges[] = {
-       { 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
-       { 16 * 385.25 /*MHz*/, 0x8e, 0x02, },
-       { 16 * 999.99        , 0x8e, 0x08, },
-};
-
-static struct tuner_params tuner_alps_tsbh1_ntsc_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_alps_tsb_1_ranges,
-               .count  = ARRAY_SIZE(tuner_alps_tsb_1_ranges),
-       },
-};
-
-/* 10-19 */
-/* ------------ TUNER_ALPS_TSBE1_PAL - TEMIC PAL ------------ */
-
-static struct tuner_params tuner_alps_tsb_1_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_alps_tsb_1_ranges,
-               .count  = ARRAY_SIZE(tuner_alps_tsb_1_ranges),
-       },
-};
-
-/* ------------ TUNER_ALPS_TSBB5_PAL_I - Alps PAL_I ------------ */
-
-static struct tuner_range tuner_alps_tsb_5_pal_ranges[] = {
-       { 16 * 133.25 /*MHz*/, 0x8e, 0x01, },
-       { 16 * 351.25 /*MHz*/, 0x8e, 0x02, },
-       { 16 * 999.99        , 0x8e, 0x08, },
-};
-
-static struct tuner_params tuner_alps_tsbb5_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_alps_tsb_5_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges),
-       },
-};
-
-/* ------------ TUNER_ALPS_TSBE5_PAL - Alps PAL ------------ */
-
-static struct tuner_params tuner_alps_tsbe5_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_alps_tsb_5_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges),
-       },
-};
-
-/* ------------ TUNER_ALPS_TSBC5_PAL - Alps PAL ------------ */
-
-static struct tuner_params tuner_alps_tsbc5_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_alps_tsb_5_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges),
-       },
-};
-
-/* ------------ TUNER_TEMIC_4006FH5_PAL - TEMIC PAL ------------ */
-
-static struct tuner_range tuner_lg_pal_ranges[] = {
-       { 16 * 170.00 /*MHz*/, 0x8e, 0xa0, },
-       { 16 * 450.00 /*MHz*/, 0x8e, 0x90, },
-       { 16 * 999.99        , 0x8e, 0x30, },
-};
-
-static struct tuner_params tuner_temic_4006fh5_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_lg_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
-       },
-};
-
-/* ------------ TUNER_ALPS_TSHC6_NTSC - Alps NTSC ------------ */
-
-static struct tuner_range tuner_alps_tshc6_ntsc_ranges[] = {
-       { 16 * 137.25 /*MHz*/, 0x8e, 0x14, },
-       { 16 * 385.25 /*MHz*/, 0x8e, 0x12, },
-       { 16 * 999.99        , 0x8e, 0x11, },
-};
-
-static struct tuner_params tuner_alps_tshc6_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_alps_tshc6_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_alps_tshc6_ntsc_ranges),
-       },
-};
-
-/* ------------ TUNER_TEMIC_PAL_DK - TEMIC PAL ------------ */
-
-static struct tuner_range tuner_temic_pal_dk_ranges[] = {
-       { 16 * 168.25 /*MHz*/, 0x8e, 0xa0, },
-       { 16 * 456.25 /*MHz*/, 0x8e, 0x90, },
-       { 16 * 999.99        , 0x8e, 0x30, },
-};
-
-static struct tuner_params tuner_temic_pal_dk_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_temic_pal_dk_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_pal_dk_ranges),
-       },
-};
-
-/* ------------ TUNER_PHILIPS_NTSC_M - Philips NTSC ------------ */
-
-static struct tuner_range tuner_philips_ntsc_m_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0x8e, 0xa0, },
-       { 16 * 454.00 /*MHz*/, 0x8e, 0x90, },
-       { 16 * 999.99        , 0x8e, 0x30, },
-};
-
-static struct tuner_params tuner_philips_ntsc_m_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_philips_ntsc_m_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_ntsc_m_ranges),
-       },
-};
-
-/* ------------ TUNER_TEMIC_4066FY5_PAL_I - TEMIC PAL_I ------------ */
-
-static struct tuner_range tuner_temic_40x6f_5_pal_ranges[] = {
-       { 16 * 169.00 /*MHz*/, 0x8e, 0xa0, },
-       { 16 * 454.00 /*MHz*/, 0x8e, 0x90, },
-       { 16 * 999.99        , 0x8e, 0x30, },
-};
-
-static struct tuner_params tuner_temic_4066fy5_pal_i_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_temic_40x6f_5_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges),
-       },
-};
-
-/* ------------ TUNER_TEMIC_4006FN5_MULTI_PAL - TEMIC PAL ------------ */
-
-static struct tuner_params tuner_temic_4006fn5_multi_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_temic_40x6f_5_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges),
-       },
-};
-
-/* 20-29 */
-/* ------------ TUNER_TEMIC_4009FR5_PAL - TEMIC PAL ------------ */
-
-static struct tuner_range tuner_temic_4009f_5_pal_ranges[] = {
-       { 16 * 141.00 /*MHz*/, 0x8e, 0xa0, },
-       { 16 * 464.00 /*MHz*/, 0x8e, 0x90, },
-       { 16 * 999.99        , 0x8e, 0x30, },
-};
-
-static struct tuner_params tuner_temic_4009f_5_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_temic_4009f_5_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
-       },
-};
-
-/* ------------ TUNER_TEMIC_4039FR5_NTSC - TEMIC NTSC ------------ */
-
-static struct tuner_range tuner_temic_4x3x_f_5_ntsc_ranges[] = {
-       { 16 * 158.00 /*MHz*/, 0x8e, 0xa0, },
-       { 16 * 453.00 /*MHz*/, 0x8e, 0x90, },
-       { 16 * 999.99        , 0x8e, 0x30, },
-};
-
-static struct tuner_params tuner_temic_4039fr5_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_temic_4x3x_f_5_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_4x3x_f_5_ntsc_ranges),
-       },
-};
-
-/* ------------ TUNER_TEMIC_4046FM5 - TEMIC PAL ------------ */
-
-static struct tuner_params tuner_temic_4046fm5_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_temic_40x6f_5_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges),
-       },
-};
-
-/* ------------ TUNER_PHILIPS_PAL_DK - Philips PAL ------------ */
-
-static struct tuner_params tuner_philips_pal_dk_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_lg_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
-       },
-};
-
-/* ------------ TUNER_PHILIPS_FQ1216ME - Philips PAL ------------ */
-
-static struct tuner_params tuner_philips_fq1216me_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_lg_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
-               .has_tda9887 = 1,
-               .port1_active = 1,
-               .port2_active = 1,
-               .port2_invert_for_secam_lc = 1,
-       },
-};
-
-/* ------------ TUNER_LG_PAL_I_FM - LGINNOTEK PAL_I ------------ */
-
-static struct tuner_params tuner_lg_pal_i_fm_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_lg_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
-       },
-};
-
-/* ------------ TUNER_LG_PAL_I - LGINNOTEK PAL_I ------------ */
-
-static struct tuner_params tuner_lg_pal_i_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_lg_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
-       },
-};
-
-/* ------------ TUNER_LG_NTSC_FM - LGINNOTEK NTSC ------------ */
-
-static struct tuner_range tuner_lg_ntsc_fm_ranges[] = {
-       { 16 * 210.00 /*MHz*/, 0x8e, 0xa0, },
-       { 16 * 497.00 /*MHz*/, 0x8e, 0x90, },
-       { 16 * 999.99        , 0x8e, 0x30, },
-};
-
-static struct tuner_params tuner_lg_ntsc_fm_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_lg_ntsc_fm_ranges,
-               .count  = ARRAY_SIZE(tuner_lg_ntsc_fm_ranges),
-       },
-};
-
-/* ------------ TUNER_LG_PAL_FM - LGINNOTEK PAL ------------ */
-
-static struct tuner_params tuner_lg_pal_fm_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_lg_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
-       },
-};
-
-/* ------------ TUNER_LG_PAL - LGINNOTEK PAL ------------ */
-
-static struct tuner_params tuner_lg_pal_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_lg_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
-       },
-};
-
-/* 30-39 */
-/* ------------ TUNER_TEMIC_4009FN5_MULTI_PAL_FM - TEMIC PAL ------------ */
-
-static struct tuner_params tuner_temic_4009_fn5_multi_pal_fm_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_temic_4009f_5_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
-       },
-};
-
-/* ------------ TUNER_SHARP_2U5JF5540_NTSC - SHARP NTSC ------------ */
-
-static struct tuner_range tuner_sharp_2u5jf5540_ntsc_ranges[] = {
-       { 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
-       { 16 * 317.25 /*MHz*/, 0x8e, 0x02, },
-       { 16 * 999.99        , 0x8e, 0x08, },
-};
-
-static struct tuner_params tuner_sharp_2u5jf5540_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_sharp_2u5jf5540_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_sharp_2u5jf5540_ntsc_ranges),
-       },
-};
-
-/* ------------ TUNER_Samsung_PAL_TCPM9091PD27 - Samsung PAL ------------ */
-
-static struct tuner_range tuner_samsung_pal_tcpm9091pd27_ranges[] = {
-       { 16 * 169 /*MHz*/, 0x8e, 0xa0, },
-       { 16 * 464 /*MHz*/, 0x8e, 0x90, },
-       { 16 * 999.99     , 0x8e, 0x30, },
-};
-
-static struct tuner_params tuner_samsung_pal_tcpm9091pd27_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_samsung_pal_tcpm9091pd27_ranges,
-               .count  = ARRAY_SIZE(tuner_samsung_pal_tcpm9091pd27_ranges),
-       },
-};
-
-/* ------------ TUNER_TEMIC_4106FH5 - TEMIC PAL ------------ */
-
-static struct tuner_params tuner_temic_4106fh5_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_temic_4009f_5_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
-       },
-};
-
-/* ------------ TUNER_TEMIC_4012FY5 - TEMIC PAL ------------ */
-
-static struct tuner_params tuner_temic_4012fy5_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_temic_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_pal_ranges),
-       },
-};
-
-/* ------------ TUNER_TEMIC_4136FY5 - TEMIC NTSC ------------ */
-
-static struct tuner_params tuner_temic_4136_fy5_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_temic_4x3x_f_5_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_4x3x_f_5_ntsc_ranges),
-       },
-};
-
-/* ------------ TUNER_LG_PAL_NEW_TAPC - LGINNOTEK PAL ------------ */
-
-static struct tuner_range tuner_lg_new_tapc_ranges[] = {
-       { 16 * 170.00 /*MHz*/, 0x8e, 0x01, },
-       { 16 * 450.00 /*MHz*/, 0x8e, 0x02, },
-       { 16 * 999.99        , 0x8e, 0x08, },
-};
-
-static struct tuner_params tuner_lg_pal_new_tapc_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_lg_new_tapc_ranges,
-               .count  = ARRAY_SIZE(tuner_lg_new_tapc_ranges),
-       },
-};
-
-/* ------------ TUNER_PHILIPS_FM1216ME_MK3 - Philips PAL ------------ */
-
-static struct tuner_range tuner_fm1216me_mk3_pal_ranges[] = {
-       { 16 * 158.00 /*MHz*/, 0x8e, 0x01, },
-       { 16 * 442.00 /*MHz*/, 0x8e, 0x02, },
-       { 16 * 999.99        , 0x8e, 0x04, },
-};
-
-static struct tuner_params tuner_fm1216me_mk3_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_fm1216me_mk3_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges),
-               .cb_first_if_lower_freq = 1,
-               .has_tda9887 = 1,
-               .port1_active = 1,
-               .port2_active = 1,
-               .port2_invert_for_secam_lc = 1,
-               .port1_fm_high_sensitivity = 1,
-               .default_top_mid = -2,
-               .default_top_secam_mid = -2,
-               .default_top_secam_high = -2,
-       },
-};
-
-/* ------------ TUNER_PHILIPS_FM1216MK5 - Philips PAL ------------ */
-
-static struct tuner_range tuner_fm1216mk5_pal_ranges[] = {
-       { 16 * 158.00 /*MHz*/, 0xce, 0x01, },
-       { 16 * 441.00 /*MHz*/, 0xce, 0x02, },
-       { 16 * 864.00        , 0xce, 0x04, },
-};
-
-static struct tuner_params tuner_fm1216mk5_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_fm1216mk5_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_fm1216mk5_pal_ranges),
-               .cb_first_if_lower_freq = 1,
-               .has_tda9887 = 1,
-               .port1_active = 1,
-               .port2_active = 1,
-               .port2_invert_for_secam_lc = 1,
-               .port1_fm_high_sensitivity = 1,
-               .default_top_mid = -2,
-               .default_top_secam_mid = -2,
-               .default_top_secam_high = -2,
-       },
-};
-
-/* ------------ TUNER_LG_NTSC_NEW_TAPC - LGINNOTEK NTSC ------------ */
-
-static struct tuner_params tuner_lg_ntsc_new_tapc_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_lg_new_tapc_ranges,
-               .count  = ARRAY_SIZE(tuner_lg_new_tapc_ranges),
-       },
-};
-
-/* 40-49 */
-/* ------------ TUNER_HITACHI_NTSC - HITACHI NTSC ------------ */
-
-static struct tuner_params tuner_hitachi_ntsc_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_lg_new_tapc_ranges,
-               .count  = ARRAY_SIZE(tuner_lg_new_tapc_ranges),
-       },
-};
-
-/* ------------ TUNER_PHILIPS_PAL_MK - Philips PAL ------------ */
-
-static struct tuner_range tuner_philips_pal_mk_pal_ranges[] = {
-       { 16 * 140.25 /*MHz*/, 0x8e, 0x01, },
-       { 16 * 463.25 /*MHz*/, 0x8e, 0xc2, },
-       { 16 * 999.99        , 0x8e, 0xcf, },
-};
-
-static struct tuner_params tuner_philips_pal_mk_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_philips_pal_mk_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_pal_mk_pal_ranges),
-       },
-};
-
-/* ---- TUNER_PHILIPS_FCV1236D - Philips FCV1236D (ATSC/NTSC) ---- */
-
-static struct tuner_range tuner_philips_fcv1236d_ntsc_ranges[] = {
-       { 16 * 157.25 /*MHz*/, 0x8e, 0xa2, },
-       { 16 * 451.25 /*MHz*/, 0x8e, 0x92, },
-       { 16 * 999.99        , 0x8e, 0x32, },
-};
-
-static struct tuner_range tuner_philips_fcv1236d_atsc_ranges[] = {
-       { 16 * 159.00 /*MHz*/, 0x8e, 0xa0, },
-       { 16 * 453.00 /*MHz*/, 0x8e, 0x90, },
-       { 16 * 999.99        , 0x8e, 0x30, },
-};
-
-static struct tuner_params tuner_philips_fcv1236d_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_philips_fcv1236d_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_fcv1236d_ntsc_ranges),
-       },
-       {
-               .type   = TUNER_PARAM_TYPE_DIGITAL,
-               .ranges = tuner_philips_fcv1236d_atsc_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_fcv1236d_atsc_ranges),
-               .iffreq = 16 * 44.00,
-       },
-};
-
-/* ------------ TUNER_PHILIPS_FM1236_MK3 - Philips NTSC ------------ */
-
-static struct tuner_range tuner_fm1236_mk3_ntsc_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0x8e, 0x01, },
-       { 16 * 442.00 /*MHz*/, 0x8e, 0x02, },
-       { 16 * 999.99        , 0x8e, 0x04, },
-};
-
-static struct tuner_params tuner_fm1236_mk3_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_fm1236_mk3_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
-               .cb_first_if_lower_freq = 1,
-               .has_tda9887 = 1,
-               .port1_active = 1,
-               .port2_active = 1,
-               .port1_fm_high_sensitivity = 1,
-       },
-};
-
-/* ------------ TUNER_PHILIPS_4IN1 - Philips NTSC ------------ */
-
-static struct tuner_params tuner_philips_4in1_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_fm1236_mk3_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
-       },
-};
-
-/* ------------ TUNER_MICROTUNE_4049FM5 - Microtune PAL ------------ */
-
-static struct tuner_params tuner_microtune_4049_fm5_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_temic_4009f_5_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
-               .has_tda9887 = 1,
-               .port1_invert_for_secam_lc = 1,
-               .default_pll_gating_18 = 1,
-               .fm_gain_normal=1,
-               .radio_if = 1, /* 33.3 MHz */
-       },
-};
-
-/* ------------ TUNER_PANASONIC_VP27 - Panasonic NTSC ------------ */
-
-static struct tuner_range tuner_panasonic_vp27_ntsc_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0xce, 0x01, },
-       { 16 * 454.00 /*MHz*/, 0xce, 0x02, },
-       { 16 * 999.99        , 0xce, 0x08, },
-};
-
-static struct tuner_params tuner_panasonic_vp27_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_panasonic_vp27_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_panasonic_vp27_ntsc_ranges),
-               .has_tda9887 = 1,
-               .intercarrier_mode = 1,
-               .default_top_low = -3,
-               .default_top_mid = -3,
-               .default_top_high = -3,
-       },
-};
-
-/* ------------ TUNER_TNF_8831BGFF - Philips PAL ------------ */
-
-static struct tuner_range tuner_tnf_8831bgff_pal_ranges[] = {
-       { 16 * 161.25 /*MHz*/, 0x8e, 0xa0, },
-       { 16 * 463.25 /*MHz*/, 0x8e, 0x90, },
-       { 16 * 999.99        , 0x8e, 0x30, },
-};
-
-static struct tuner_params tuner_tnf_8831bgff_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_tnf_8831bgff_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_tnf_8831bgff_pal_ranges),
-       },
-};
-
-/* ------------ TUNER_MICROTUNE_4042FI5 - Microtune NTSC ------------ */
-
-static struct tuner_range tuner_microtune_4042fi5_ntsc_ranges[] = {
-       { 16 * 162.00 /*MHz*/, 0x8e, 0xa2, },
-       { 16 * 457.00 /*MHz*/, 0x8e, 0x94, },
-       { 16 * 999.99        , 0x8e, 0x31, },
-};
-
-static struct tuner_range tuner_microtune_4042fi5_atsc_ranges[] = {
-       { 16 * 162.00 /*MHz*/, 0x8e, 0xa1, },
-       { 16 * 457.00 /*MHz*/, 0x8e, 0x91, },
-       { 16 * 999.99        , 0x8e, 0x31, },
-};
-
-static struct tuner_params tuner_microtune_4042fi5_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_microtune_4042fi5_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_microtune_4042fi5_ntsc_ranges),
-       },
-       {
-               .type   = TUNER_PARAM_TYPE_DIGITAL,
-               .ranges = tuner_microtune_4042fi5_atsc_ranges,
-               .count  = ARRAY_SIZE(tuner_microtune_4042fi5_atsc_ranges),
-               .iffreq = 16 * 44.00 /*MHz*/,
-       },
-};
-
-/* 50-59 */
-/* ------------ TUNER_TCL_2002N - TCL NTSC ------------ */
-
-static struct tuner_range tuner_tcl_2002n_ntsc_ranges[] = {
-       { 16 * 172.00 /*MHz*/, 0x8e, 0x01, },
-       { 16 * 448.00 /*MHz*/, 0x8e, 0x02, },
-       { 16 * 999.99        , 0x8e, 0x08, },
-};
-
-static struct tuner_params tuner_tcl_2002n_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_tcl_2002n_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_tcl_2002n_ntsc_ranges),
-               .cb_first_if_lower_freq = 1,
-       },
-};
-
-/* ------------ TUNER_PHILIPS_FM1256_IH3 - Philips PAL ------------ */
-
-static struct tuner_params tuner_philips_fm1256_ih3_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_fm1236_mk3_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
-               .radio_if = 1, /* 33.3 MHz */
-       },
-};
-
-/* ------------ TUNER_THOMSON_DTT7610 - THOMSON ATSC ------------ */
-
-/* single range used for both ntsc and atsc */
-static struct tuner_range tuner_thomson_dtt7610_ntsc_ranges[] = {
-       { 16 * 157.25 /*MHz*/, 0x8e, 0x39, },
-       { 16 * 454.00 /*MHz*/, 0x8e, 0x3a, },
-       { 16 * 999.99        , 0x8e, 0x3c, },
-};
-
-static struct tuner_params tuner_thomson_dtt7610_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_thomson_dtt7610_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_thomson_dtt7610_ntsc_ranges),
-       },
-       {
-               .type   = TUNER_PARAM_TYPE_DIGITAL,
-               .ranges = tuner_thomson_dtt7610_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_thomson_dtt7610_ntsc_ranges),
-               .iffreq = 16 * 44.00 /*MHz*/,
-       },
-};
-
-/* ------------ TUNER_PHILIPS_FQ1286 - Philips NTSC ------------ */
-
-static struct tuner_range tuner_philips_fq1286_ntsc_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0x8e, 0x41, },
-       { 16 * 454.00 /*MHz*/, 0x8e, 0x42, },
-       { 16 * 999.99        , 0x8e, 0x04, },
-};
-
-static struct tuner_params tuner_philips_fq1286_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_philips_fq1286_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_fq1286_ntsc_ranges),
-       },
-};
-
-/* ------------ TUNER_TCL_2002MB - TCL PAL ------------ */
-
-static struct tuner_range tuner_tcl_2002mb_pal_ranges[] = {
-       { 16 * 170.00 /*MHz*/, 0xce, 0x01, },
-       { 16 * 450.00 /*MHz*/, 0xce, 0x02, },
-       { 16 * 999.99        , 0xce, 0x08, },
-};
-
-static struct tuner_params tuner_tcl_2002mb_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_tcl_2002mb_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_tcl_2002mb_pal_ranges),
-       },
-};
-
-/* ------------ TUNER_PHILIPS_FQ1216AME_MK4 - Philips PAL ------------ */
-
-static struct tuner_range tuner_philips_fq12_6a___mk4_pal_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0xce, 0x01, },
-       { 16 * 442.00 /*MHz*/, 0xce, 0x02, },
-       { 16 * 999.99        , 0xce, 0x04, },
-};
-
-static struct tuner_params tuner_philips_fq1216ame_mk4_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_philips_fq12_6a___mk4_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_fq12_6a___mk4_pal_ranges),
-               .has_tda9887 = 1,
-               .port1_active = 1,
-               .port2_invert_for_secam_lc = 1,
-               .default_top_mid = -2,
-               .default_top_secam_low = -2,
-               .default_top_secam_mid = -2,
-               .default_top_secam_high = -2,
-       },
-};
-
-/* ------------ TUNER_PHILIPS_FQ1236A_MK4 - Philips NTSC ------------ */
-
-static struct tuner_params tuner_philips_fq1236a_mk4_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_fm1236_mk3_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
-       },
-};
-
-/* ------------ TUNER_YMEC_TVF_8531MF - Philips NTSC ------------ */
-
-static struct tuner_params tuner_ymec_tvf_8531mf_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_philips_ntsc_m_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_ntsc_m_ranges),
-       },
-};
-
-/* ------------ TUNER_YMEC_TVF_5533MF - Philips NTSC ------------ */
-
-static struct tuner_range tuner_ymec_tvf_5533mf_ntsc_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0x8e, 0x01, },
-       { 16 * 454.00 /*MHz*/, 0x8e, 0x02, },
-       { 16 * 999.99        , 0x8e, 0x04, },
-};
-
-static struct tuner_params tuner_ymec_tvf_5533mf_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_ymec_tvf_5533mf_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_ymec_tvf_5533mf_ntsc_ranges),
-       },
-};
-
-/* 60-69 */
-/* ------------ TUNER_THOMSON_DTT761X - THOMSON ATSC ------------ */
-/* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
-
-static struct tuner_range tuner_thomson_dtt761x_ntsc_ranges[] = {
-       { 16 * 145.25 /*MHz*/, 0x8e, 0x39, },
-       { 16 * 415.25 /*MHz*/, 0x8e, 0x3a, },
-       { 16 * 999.99        , 0x8e, 0x3c, },
-};
-
-static struct tuner_range tuner_thomson_dtt761x_atsc_ranges[] = {
-       { 16 * 147.00 /*MHz*/, 0x8e, 0x39, },
-       { 16 * 417.00 /*MHz*/, 0x8e, 0x3a, },
-       { 16 * 999.99        , 0x8e, 0x3c, },
-};
-
-static struct tuner_params tuner_thomson_dtt761x_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_thomson_dtt761x_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_thomson_dtt761x_ntsc_ranges),
-               .has_tda9887 = 1,
-               .fm_gain_normal = 1,
-               .radio_if = 2, /* 41.3 MHz */
-       },
-       {
-               .type   = TUNER_PARAM_TYPE_DIGITAL,
-               .ranges = tuner_thomson_dtt761x_atsc_ranges,
-               .count  = ARRAY_SIZE(tuner_thomson_dtt761x_atsc_ranges),
-               .iffreq = 16 * 44.00, /*MHz*/
-       },
-};
-
-/* ------------ TUNER_TENA_9533_DI - Philips PAL ------------ */
-
-static struct tuner_range tuner_tena_9533_di_pal_ranges[] = {
-       { 16 * 160.25 /*MHz*/, 0x8e, 0x01, },
-       { 16 * 464.25 /*MHz*/, 0x8e, 0x02, },
-       { 16 * 999.99        , 0x8e, 0x04, },
-};
-
-static struct tuner_params tuner_tena_9533_di_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_tena_9533_di_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_tena_9533_di_pal_ranges),
-       },
-};
-
-/* ------------ TUNER_TENA_TNF_5337 - Tena tnf5337MFD STD M/N ------------ */
-
-static struct tuner_range tuner_tena_tnf_5337_ntsc_ranges[] = {
-       { 16 * 166.25 /*MHz*/, 0x86, 0x01, },
-       { 16 * 466.25 /*MHz*/, 0x86, 0x02, },
-       { 16 * 999.99        , 0x86, 0x08, },
-};
-
-static struct tuner_params tuner_tena_tnf_5337_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_tena_tnf_5337_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_tena_tnf_5337_ntsc_ranges),
-       },
-};
-
-/* ------------ TUNER_PHILIPS_FMD1216ME(X)_MK3 - Philips PAL ------------ */
-
-static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0x86, 0x51, },
-       { 16 * 442.00 /*MHz*/, 0x86, 0x52, },
-       { 16 * 999.99        , 0x86, 0x54, },
-};
-
-static struct tuner_range tuner_philips_fmd1216me_mk3_dvb_ranges[] = {
-       { 16 * 143.87 /*MHz*/, 0xbc, 0x41 },
-       { 16 * 158.87 /*MHz*/, 0xf4, 0x41 },
-       { 16 * 329.87 /*MHz*/, 0xbc, 0x42 },
-       { 16 * 441.87 /*MHz*/, 0xf4, 0x42 },
-       { 16 * 625.87 /*MHz*/, 0xbc, 0x44 },
-       { 16 * 803.87 /*MHz*/, 0xf4, 0x44 },
-       { 16 * 999.99        , 0xfc, 0x44 },
-};
-
-static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_philips_fmd1216me_mk3_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_pal_ranges),
-               .has_tda9887 = 1,
-               .port1_active = 1,
-               .port2_active = 1,
-               .port2_fm_high_sensitivity = 1,
-               .port2_invert_for_secam_lc = 1,
-               .port1_set_for_fm_mono = 1,
-       },
-       {
-               .type   = TUNER_PARAM_TYPE_DIGITAL,
-               .ranges = tuner_philips_fmd1216me_mk3_dvb_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_dvb_ranges),
-               .iffreq = 16 * 36.125, /*MHz*/
-       },
-};
-
-static struct tuner_params tuner_philips_fmd1216mex_mk3_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_philips_fmd1216me_mk3_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_pal_ranges),
-               .has_tda9887 = 1,
-               .port1_active = 1,
-               .port2_active = 1,
-               .port2_fm_high_sensitivity = 1,
-               .port2_invert_for_secam_lc = 1,
-               .port1_set_for_fm_mono = 1,
-               .radio_if = 1,
-               .fm_gain_normal = 1,
-       },
-       {
-               .type   = TUNER_PARAM_TYPE_DIGITAL,
-               .ranges = tuner_philips_fmd1216me_mk3_dvb_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_dvb_ranges),
-               .iffreq = 16 * 36.125, /*MHz*/
-       },
-};
-
-/* ------ TUNER_LG_TDVS_H06XF - LG INNOTEK / INFINEON ATSC ----- */
-
-static struct tuner_range tuner_tua6034_ntsc_ranges[] = {
-       { 16 * 165.00 /*MHz*/, 0x8e, 0x01 },
-       { 16 * 450.00 /*MHz*/, 0x8e, 0x02 },
-       { 16 * 999.99        , 0x8e, 0x04 },
-};
-
-static struct tuner_range tuner_tua6034_atsc_ranges[] = {
-       { 16 * 165.00 /*MHz*/, 0xce, 0x01 },
-       { 16 * 450.00 /*MHz*/, 0xce, 0x02 },
-       { 16 * 999.99        , 0xce, 0x04 },
-};
-
-static struct tuner_params tuner_lg_tdvs_h06xf_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_tua6034_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_tua6034_ntsc_ranges),
-       },
-       {
-               .type   = TUNER_PARAM_TYPE_DIGITAL,
-               .ranges = tuner_tua6034_atsc_ranges,
-               .count  = ARRAY_SIZE(tuner_tua6034_atsc_ranges),
-               .iffreq = 16 * 44.00,
-       },
-};
-
-/* ------------ TUNER_YMEC_TVF66T5_B_DFF - Philips PAL ------------ */
-
-static struct tuner_range tuner_ymec_tvf66t5_b_dff_pal_ranges[] = {
-       { 16 * 160.25 /*MHz*/, 0x8e, 0x01, },
-       { 16 * 464.25 /*MHz*/, 0x8e, 0x02, },
-       { 16 * 999.99        , 0x8e, 0x08, },
-};
-
-static struct tuner_params tuner_ymec_tvf66t5_b_dff_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_ymec_tvf66t5_b_dff_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_ymec_tvf66t5_b_dff_pal_ranges),
-       },
-};
-
-/* ------------ TUNER_LG_NTSC_TALN_MINI - LGINNOTEK NTSC ------------ */
-
-static struct tuner_range tuner_lg_taln_ntsc_ranges[] = {
-       { 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
-       { 16 * 373.25 /*MHz*/, 0x8e, 0x02, },
-       { 16 * 999.99        , 0x8e, 0x08, },
-};
-
-static struct tuner_range tuner_lg_taln_pal_secam_ranges[] = {
-       { 16 * 150.00 /*MHz*/, 0x8e, 0x01, },
-       { 16 * 425.00 /*MHz*/, 0x8e, 0x02, },
-       { 16 * 999.99        , 0x8e, 0x08, },
-};
-
-static struct tuner_params tuner_lg_taln_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_lg_taln_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_lg_taln_ntsc_ranges),
-       },{
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_lg_taln_pal_secam_ranges,
-               .count  = ARRAY_SIZE(tuner_lg_taln_pal_secam_ranges),
-       },
-};
-
-/* ------------ TUNER_PHILIPS_TD1316 - Philips PAL ------------ */
-
-static struct tuner_range tuner_philips_td1316_pal_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0xc8, 0xa1, },
-       { 16 * 442.00 /*MHz*/, 0xc8, 0xa2, },
-       { 16 * 999.99        , 0xc8, 0xa4, },
-};
-
-static struct tuner_range tuner_philips_td1316_dvb_ranges[] = {
-       { 16 *  93.834 /*MHz*/, 0xca, 0x60, },
-       { 16 * 123.834 /*MHz*/, 0xca, 0xa0, },
-       { 16 * 163.834 /*MHz*/, 0xca, 0xc0, },
-       { 16 * 253.834 /*MHz*/, 0xca, 0x60, },
-       { 16 * 383.834 /*MHz*/, 0xca, 0xa0, },
-       { 16 * 443.834 /*MHz*/, 0xca, 0xc0, },
-       { 16 * 583.834 /*MHz*/, 0xca, 0x60, },
-       { 16 * 793.834 /*MHz*/, 0xca, 0xa0, },
-       { 16 * 999.999        , 0xca, 0xe0, },
-};
-
-static struct tuner_params tuner_philips_td1316_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_philips_td1316_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_td1316_pal_ranges),
-       },
-       {
-               .type   = TUNER_PARAM_TYPE_DIGITAL,
-               .ranges = tuner_philips_td1316_dvb_ranges,
-               .count  = ARRAY_SIZE(tuner_philips_td1316_dvb_ranges),
-               .iffreq = 16 * 36.166667 /*MHz*/,
-       },
-};
-
-/* ------------ TUNER_PHILIPS_TUV1236D - Philips ATSC ------------ */
-
-static struct tuner_range tuner_tuv1236d_ntsc_ranges[] = {
-       { 16 * 157.25 /*MHz*/, 0xce, 0x01, },
-       { 16 * 454.00 /*MHz*/, 0xce, 0x02, },
-       { 16 * 999.99        , 0xce, 0x04, },
-};
-
-static struct tuner_range tuner_tuv1236d_atsc_ranges[] = {
-       { 16 * 157.25 /*MHz*/, 0xc6, 0x41, },
-       { 16 * 454.00 /*MHz*/, 0xc6, 0x42, },
-       { 16 * 999.99        , 0xc6, 0x44, },
-};
-
-static struct tuner_params tuner_tuv1236d_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_tuv1236d_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_tuv1236d_ntsc_ranges),
-       },
-       {
-               .type   = TUNER_PARAM_TYPE_DIGITAL,
-               .ranges = tuner_tuv1236d_atsc_ranges,
-               .count  = ARRAY_SIZE(tuner_tuv1236d_atsc_ranges),
-               .iffreq = 16 * 44.00,
-       },
-};
-
-/* ------------ TUNER_TNF_xxx5  - Texas Instruments--------- */
-/* This is known to work with Tenna TVF58t5-MFF and TVF5835 MFF
- *     but it is expected to work also with other Tenna/Ymec
- *     models based on TI SN 761677 chip on both PAL and NTSC
- */
-
-static struct tuner_range tuner_tnf_5335_d_if_pal_ranges[] = {
-       { 16 * 168.25 /*MHz*/, 0x8e, 0x01, },
-       { 16 * 471.25 /*MHz*/, 0x8e, 0x02, },
-       { 16 * 999.99        , 0x8e, 0x08, },
-};
-
-static struct tuner_range tuner_tnf_5335mf_ntsc_ranges[] = {
-       { 16 * 169.25 /*MHz*/, 0x8e, 0x01, },
-       { 16 * 469.25 /*MHz*/, 0x8e, 0x02, },
-       { 16 * 999.99        , 0x8e, 0x08, },
-};
-
-static struct tuner_params tuner_tnf_5335mf_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_tnf_5335mf_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_tnf_5335mf_ntsc_ranges),
-       },
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_tnf_5335_d_if_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_tnf_5335_d_if_pal_ranges),
-       },
-};
-
-/* 70-79 */
-/* ------------ TUNER_SAMSUNG_TCPN_2121P30A - Samsung NTSC ------------ */
-
-/* '+ 4' turns on the Low Noise Amplifier */
-static struct tuner_range tuner_samsung_tcpn_2121p30a_ntsc_ranges[] = {
-       { 16 * 130.00 /*MHz*/, 0xce, 0x01 + 4, },
-       { 16 * 364.50 /*MHz*/, 0xce, 0x02 + 4, },
-       { 16 * 999.99        , 0xce, 0x08 + 4, },
-};
-
-static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_samsung_tcpn_2121p30a_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_ntsc_ranges),
-       },
-};
-
-/* ------------ TUNER_THOMSON_FE6600 - DViCO Hybrid PAL ------------ */
-
-static struct tuner_range tuner_thomson_fe6600_pal_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0xfe, 0x11, },
-       { 16 * 442.00 /*MHz*/, 0xf6, 0x12, },
-       { 16 * 999.99        , 0xf6, 0x18, },
-};
-
-static struct tuner_range tuner_thomson_fe6600_dvb_ranges[] = {
-       { 16 * 250.00 /*MHz*/, 0xb4, 0x12, },
-       { 16 * 455.00 /*MHz*/, 0xfe, 0x11, },
-       { 16 * 775.50 /*MHz*/, 0xbc, 0x18, },
-       { 16 * 999.99        , 0xf4, 0x18, },
-};
-
-static struct tuner_params tuner_thomson_fe6600_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_thomson_fe6600_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_thomson_fe6600_pal_ranges),
-       },
-       {
-               .type   = TUNER_PARAM_TYPE_DIGITAL,
-               .ranges = tuner_thomson_fe6600_dvb_ranges,
-               .count  = ARRAY_SIZE(tuner_thomson_fe6600_dvb_ranges),
-               .iffreq = 16 * 36.125 /*MHz*/,
-       },
-};
-
-/* ------------ TUNER_SAMSUNG_TCPG_6121P30A - Samsung PAL ------------ */
-
-/* '+ 4' turns on the Low Noise Amplifier */
-static struct tuner_range tuner_samsung_tcpg_6121p30a_pal_ranges[] = {
-       { 16 * 146.25 /*MHz*/, 0xce, 0x01 + 4, },
-       { 16 * 428.50 /*MHz*/, 0xce, 0x02 + 4, },
-       { 16 * 999.99        , 0xce, 0x08 + 4, },
-};
-
-static struct tuner_params tuner_samsung_tcpg_6121p30a_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_samsung_tcpg_6121p30a_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_pal_ranges),
-               .has_tda9887 = 1,
-               .port1_active = 1,
-               .port2_active = 1,
-               .port2_invert_for_secam_lc = 1,
-       },
-};
-
-/* ------------ TUNER_TCL_MF02GIP-5N-E - TCL MF02GIP-5N ------------ */
-
-static struct tuner_range tuner_tcl_mf02gip_5n_ntsc_ranges[] = {
-       { 16 * 172.00 /*MHz*/, 0x8e, 0x01, },
-       { 16 * 448.00 /*MHz*/, 0x8e, 0x02, },
-       { 16 * 999.99        , 0x8e, 0x04, },
-};
-
-static struct tuner_params tuner_tcl_mf02gip_5n_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_tcl_mf02gip_5n_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_tcl_mf02gip_5n_ntsc_ranges),
-               .cb_first_if_lower_freq = 1,
-       },
-};
-
-/* 80-89 */
-/* --------- TUNER_PHILIPS_FQ1216LME_MK3 -- active loopthrough, no FM ------- */
-
-static struct tuner_params tuner_fq1216lme_mk3_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_PAL,
-               .ranges = tuner_fm1216me_mk3_pal_ranges,
-               .count  = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges),
-               .cb_first_if_lower_freq = 1, /* not specified, but safe to do */
-               .has_tda9887 = 1, /* TDA9886 */
-               .port1_active = 1,
-               .port2_active = 1,
-               .port2_invert_for_secam_lc = 1,
-               .default_top_low = 4,
-               .default_top_mid = 4,
-               .default_top_high = 4,
-               .default_top_secam_low = 4,
-               .default_top_secam_mid = 4,
-               .default_top_secam_high = 4,
-       },
-};
-
-/* ----- TUNER_PARTSNIC_PTI_5NF05 - Partsnic (Daewoo) PTI-5NF05 NTSC ----- */
-
-static struct tuner_range tuner_partsnic_pti_5nf05_ranges[] = {
-       /* The datasheet specified channel ranges and the bandswitch byte */
-       /* The control byte value of 0x8e is just a guess */
-       { 16 * 133.25 /*MHz*/, 0x8e, 0x01, }, /* Channels    2 -    B */
-       { 16 * 367.25 /*MHz*/, 0x8e, 0x02, }, /* Channels    C - W+11 */
-       { 16 * 999.99        , 0x8e, 0x08, }, /* Channels W+12 -   69 */
-};
-
-static struct tuner_params tuner_partsnic_pti_5nf05_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_partsnic_pti_5nf05_ranges,
-               .count  = ARRAY_SIZE(tuner_partsnic_pti_5nf05_ranges),
-               .cb_first_if_lower_freq = 1, /* not specified but safe to do */
-       },
-};
-
-/* --------- TUNER_PHILIPS_CU1216L - DVB-C NIM ------------------------- */
-
-static struct tuner_range tuner_cu1216l_ranges[] = {
-       { 16 * 160.25 /*MHz*/, 0xce, 0x01 },
-       { 16 * 444.25 /*MHz*/, 0xce, 0x02 },
-       { 16 * 999.99        , 0xce, 0x04 },
-};
-
-static struct tuner_params tuner_philips_cu1216l_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_DIGITAL,
-               .ranges = tuner_cu1216l_ranges,
-               .count  = ARRAY_SIZE(tuner_cu1216l_ranges),
-               .iffreq = 16 * 36.125, /*MHz*/
-       },
-};
-
-/* ---------------------- TUNER_SONY_BTF_PXN01Z ------------------------ */
-
-static struct tuner_range tuner_sony_btf_pxn01z_ranges[] = {
-       { 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
-       { 16 * 367.25 /*MHz*/, 0x8e, 0x02, },
-       { 16 * 999.99        , 0x8e, 0x04, },
-};
-
-static struct tuner_params tuner_sony_btf_pxn01z_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_sony_btf_pxn01z_ranges,
-               .count  = ARRAY_SIZE(tuner_sony_btf_pxn01z_ranges),
-       },
-};
-
-/* ------------ TUNER_PHILIPS_FQ1236_MK5 - Philips NTSC ------------ */
-
-static struct tuner_params tuner_philips_fq1236_mk5_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_fm1236_mk3_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
-               .has_tda9887 = 1, /* TDA9885, no FM radio */
-       },
-};
-
-/* --------------------------------------------------------------------- */
-
-struct tunertype tuners[] = {
-       /* 0-9 */
-       [TUNER_TEMIC_PAL] = { /* TEMIC PAL */
-               .name   = "Temic PAL (4002 FH5)",
-               .params = tuner_temic_pal_params,
-               .count  = ARRAY_SIZE(tuner_temic_pal_params),
-       },
-       [TUNER_PHILIPS_PAL_I] = { /* Philips PAL_I */
-               .name   = "Philips PAL_I (FI1246 and compatibles)",
-               .params = tuner_philips_pal_i_params,
-               .count  = ARRAY_SIZE(tuner_philips_pal_i_params),
-       },
-       [TUNER_PHILIPS_NTSC] = { /* Philips NTSC */
-               .name   = "Philips NTSC (FI1236,FM1236 and compatibles)",
-               .params = tuner_philips_ntsc_params,
-               .count  = ARRAY_SIZE(tuner_philips_ntsc_params),
-       },
-       [TUNER_PHILIPS_SECAM] = { /* Philips SECAM */
-               .name   = "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)",
-               .params = tuner_philips_secam_params,
-               .count  = ARRAY_SIZE(tuner_philips_secam_params),
-       },
-       [TUNER_ABSENT] = { /* Tuner Absent */
-               .name   = "NoTuner",
-       },
-       [TUNER_PHILIPS_PAL] = { /* Philips PAL */
-               .name   = "Philips PAL_BG (FI1216 and compatibles)",
-               .params = tuner_philips_pal_params,
-               .count  = ARRAY_SIZE(tuner_philips_pal_params),
-       },
-       [TUNER_TEMIC_NTSC] = { /* TEMIC NTSC */
-               .name   = "Temic NTSC (4032 FY5)",
-               .params = tuner_temic_ntsc_params,
-               .count  = ARRAY_SIZE(tuner_temic_ntsc_params),
-       },
-       [TUNER_TEMIC_PAL_I] = { /* TEMIC PAL_I */
-               .name   = "Temic PAL_I (4062 FY5)",
-               .params = tuner_temic_pal_i_params,
-               .count  = ARRAY_SIZE(tuner_temic_pal_i_params),
-       },
-       [TUNER_TEMIC_4036FY5_NTSC] = { /* TEMIC NTSC */
-               .name   = "Temic NTSC (4036 FY5)",
-               .params = tuner_temic_4036fy5_ntsc_params,
-               .count  = ARRAY_SIZE(tuner_temic_4036fy5_ntsc_params),
-       },
-       [TUNER_ALPS_TSBH1_NTSC] = { /* TEMIC NTSC */
-               .name   = "Alps HSBH1",
-               .params = tuner_alps_tsbh1_ntsc_params,
-               .count  = ARRAY_SIZE(tuner_alps_tsbh1_ntsc_params),
-       },
-
-       /* 10-19 */
-       [TUNER_ALPS_TSBE1_PAL] = { /* TEMIC PAL */
-               .name   = "Alps TSBE1",
-               .params = tuner_alps_tsb_1_params,
-               .count  = ARRAY_SIZE(tuner_alps_tsb_1_params),
-       },
-       [TUNER_ALPS_TSBB5_PAL_I] = { /* Alps PAL_I */
-               .name   = "Alps TSBB5",
-               .params = tuner_alps_tsbb5_params,
-               .count  = ARRAY_SIZE(tuner_alps_tsbb5_params),
-       },
-       [TUNER_ALPS_TSBE5_PAL] = { /* Alps PAL */
-               .name   = "Alps TSBE5",
-               .params = tuner_alps_tsbe5_params,
-               .count  = ARRAY_SIZE(tuner_alps_tsbe5_params),
-       },
-       [TUNER_ALPS_TSBC5_PAL] = { /* Alps PAL */
-               .name   = "Alps TSBC5",
-               .params = tuner_alps_tsbc5_params,
-               .count  = ARRAY_SIZE(tuner_alps_tsbc5_params),
-       },
-       [TUNER_TEMIC_4006FH5_PAL] = { /* TEMIC PAL */
-               .name   = "Temic PAL_BG (4006FH5)",
-               .params = tuner_temic_4006fh5_params,
-               .count  = ARRAY_SIZE(tuner_temic_4006fh5_params),
-       },
-       [TUNER_ALPS_TSHC6_NTSC] = { /* Alps NTSC */
-               .name   = "Alps TSCH6",
-               .params = tuner_alps_tshc6_params,
-               .count  = ARRAY_SIZE(tuner_alps_tshc6_params),
-       },
-       [TUNER_TEMIC_PAL_DK] = { /* TEMIC PAL */
-               .name   = "Temic PAL_DK (4016 FY5)",
-               .params = tuner_temic_pal_dk_params,
-               .count  = ARRAY_SIZE(tuner_temic_pal_dk_params),
-       },
-       [TUNER_PHILIPS_NTSC_M] = { /* Philips NTSC */
-               .name   = "Philips NTSC_M (MK2)",
-               .params = tuner_philips_ntsc_m_params,
-               .count  = ARRAY_SIZE(tuner_philips_ntsc_m_params),
-       },
-       [TUNER_TEMIC_4066FY5_PAL_I] = { /* TEMIC PAL_I */
-               .name   = "Temic PAL_I (4066 FY5)",
-               .params = tuner_temic_4066fy5_pal_i_params,
-               .count  = ARRAY_SIZE(tuner_temic_4066fy5_pal_i_params),
-       },
-       [TUNER_TEMIC_4006FN5_MULTI_PAL] = { /* TEMIC PAL */
-               .name   = "Temic PAL* auto (4006 FN5)",
-               .params = tuner_temic_4006fn5_multi_params,
-               .count  = ARRAY_SIZE(tuner_temic_4006fn5_multi_params),
-       },
-
-       /* 20-29 */
-       [TUNER_TEMIC_4009FR5_PAL] = { /* TEMIC PAL */
-               .name   = "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)",
-               .params = tuner_temic_4009f_5_params,
-               .count  = ARRAY_SIZE(tuner_temic_4009f_5_params),
-       },
-       [TUNER_TEMIC_4039FR5_NTSC] = { /* TEMIC NTSC */
-               .name   = "Temic NTSC (4039 FR5)",
-               .params = tuner_temic_4039fr5_params,
-               .count  = ARRAY_SIZE(tuner_temic_4039fr5_params),
-       },
-       [TUNER_TEMIC_4046FM5] = { /* TEMIC PAL */
-               .name   = "Temic PAL/SECAM multi (4046 FM5)",
-               .params = tuner_temic_4046fm5_params,
-               .count  = ARRAY_SIZE(tuner_temic_4046fm5_params),
-       },
-       [TUNER_PHILIPS_PAL_DK] = { /* Philips PAL */
-               .name   = "Philips PAL_DK (FI1256 and compatibles)",
-               .params = tuner_philips_pal_dk_params,
-               .count  = ARRAY_SIZE(tuner_philips_pal_dk_params),
-       },
-       [TUNER_PHILIPS_FQ1216ME] = { /* Philips PAL */
-               .name   = "Philips PAL/SECAM multi (FQ1216ME)",
-               .params = tuner_philips_fq1216me_params,
-               .count  = ARRAY_SIZE(tuner_philips_fq1216me_params),
-       },
-       [TUNER_LG_PAL_I_FM] = { /* LGINNOTEK PAL_I */
-               .name   = "LG PAL_I+FM (TAPC-I001D)",
-               .params = tuner_lg_pal_i_fm_params,
-               .count  = ARRAY_SIZE(tuner_lg_pal_i_fm_params),
-       },
-       [TUNER_LG_PAL_I] = { /* LGINNOTEK PAL_I */
-               .name   = "LG PAL_I (TAPC-I701D)",
-               .params = tuner_lg_pal_i_params,
-               .count  = ARRAY_SIZE(tuner_lg_pal_i_params),
-       },
-       [TUNER_LG_NTSC_FM] = { /* LGINNOTEK NTSC */
-               .name   = "LG NTSC+FM (TPI8NSR01F)",
-               .params = tuner_lg_ntsc_fm_params,
-               .count  = ARRAY_SIZE(tuner_lg_ntsc_fm_params),
-       },
-       [TUNER_LG_PAL_FM] = { /* LGINNOTEK PAL */
-               .name   = "LG PAL_BG+FM (TPI8PSB01D)",
-               .params = tuner_lg_pal_fm_params,
-               .count  = ARRAY_SIZE(tuner_lg_pal_fm_params),
-       },
-       [TUNER_LG_PAL] = { /* LGINNOTEK PAL */
-               .name   = "LG PAL_BG (TPI8PSB11D)",
-               .params = tuner_lg_pal_params,
-               .count  = ARRAY_SIZE(tuner_lg_pal_params),
-       },
-
-       /* 30-39 */
-       [TUNER_TEMIC_4009FN5_MULTI_PAL_FM] = { /* TEMIC PAL */
-               .name   = "Temic PAL* auto + FM (4009 FN5)",
-               .params = tuner_temic_4009_fn5_multi_pal_fm_params,
-               .count  = ARRAY_SIZE(tuner_temic_4009_fn5_multi_pal_fm_params),
-       },
-       [TUNER_SHARP_2U5JF5540_NTSC] = { /* SHARP NTSC */
-               .name   = "SHARP NTSC_JP (2U5JF5540)",
-               .params = tuner_sharp_2u5jf5540_params,
-               .count  = ARRAY_SIZE(tuner_sharp_2u5jf5540_params),
-       },
-       [TUNER_Samsung_PAL_TCPM9091PD27] = { /* Samsung PAL */
-               .name   = "Samsung PAL TCPM9091PD27",
-               .params = tuner_samsung_pal_tcpm9091pd27_params,
-               .count  = ARRAY_SIZE(tuner_samsung_pal_tcpm9091pd27_params),
-       },
-       [TUNER_MT2032] = { /* Microtune PAL|NTSC */
-               .name   = "MT20xx universal",
-               /* see mt20xx.c for details */ },
-       [TUNER_TEMIC_4106FH5] = { /* TEMIC PAL */
-               .name   = "Temic PAL_BG (4106 FH5)",
-               .params = tuner_temic_4106fh5_params,
-               .count  = ARRAY_SIZE(tuner_temic_4106fh5_params),
-       },
-       [TUNER_TEMIC_4012FY5] = { /* TEMIC PAL */
-               .name   = "Temic PAL_DK/SECAM_L (4012 FY5)",
-               .params = tuner_temic_4012fy5_params,
-               .count  = ARRAY_SIZE(tuner_temic_4012fy5_params),
-       },
-       [TUNER_TEMIC_4136FY5] = { /* TEMIC NTSC */
-               .name   = "Temic NTSC (4136 FY5)",
-               .params = tuner_temic_4136_fy5_params,
-               .count  = ARRAY_SIZE(tuner_temic_4136_fy5_params),
-       },
-       [TUNER_LG_PAL_NEW_TAPC] = { /* LGINNOTEK PAL */
-               .name   = "LG PAL (newer TAPC series)",
-               .params = tuner_lg_pal_new_tapc_params,
-               .count  = ARRAY_SIZE(tuner_lg_pal_new_tapc_params),
-       },
-       [TUNER_PHILIPS_FM1216ME_MK3] = { /* Philips PAL */
-               .name   = "Philips PAL/SECAM multi (FM1216ME MK3)",
-               .params = tuner_fm1216me_mk3_params,
-               .count  = ARRAY_SIZE(tuner_fm1216me_mk3_params),
-       },
-       [TUNER_LG_NTSC_NEW_TAPC] = { /* LGINNOTEK NTSC */
-               .name   = "LG NTSC (newer TAPC series)",
-               .params = tuner_lg_ntsc_new_tapc_params,
-               .count  = ARRAY_SIZE(tuner_lg_ntsc_new_tapc_params),
-       },
-
-       /* 40-49 */
-       [TUNER_HITACHI_NTSC] = { /* HITACHI NTSC */
-               .name   = "HITACHI V7-J180AT",
-               .params = tuner_hitachi_ntsc_params,
-               .count  = ARRAY_SIZE(tuner_hitachi_ntsc_params),
-       },
-       [TUNER_PHILIPS_PAL_MK] = { /* Philips PAL */
-               .name   = "Philips PAL_MK (FI1216 MK)",
-               .params = tuner_philips_pal_mk_params,
-               .count  = ARRAY_SIZE(tuner_philips_pal_mk_params),
-       },
-       [TUNER_PHILIPS_FCV1236D] = { /* Philips ATSC */
-               .name   = "Philips FCV1236D ATSC/NTSC dual in",
-               .params = tuner_philips_fcv1236d_params,
-               .count  = ARRAY_SIZE(tuner_philips_fcv1236d_params),
-               .min = 16 *  53.00,
-               .max = 16 * 803.00,
-               .stepsize = 62500,
-       },
-       [TUNER_PHILIPS_FM1236_MK3] = { /* Philips NTSC */
-               .name   = "Philips NTSC MK3 (FM1236MK3 or FM1236/F)",
-               .params = tuner_fm1236_mk3_params,
-               .count  = ARRAY_SIZE(tuner_fm1236_mk3_params),
-       },
-       [TUNER_PHILIPS_4IN1] = { /* Philips NTSC */
-               .name   = "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)",
-               .params = tuner_philips_4in1_params,
-               .count  = ARRAY_SIZE(tuner_philips_4in1_params),
-       },
-       [TUNER_MICROTUNE_4049FM5] = { /* Microtune PAL */
-               .name   = "Microtune 4049 FM5",
-               .params = tuner_microtune_4049_fm5_params,
-               .count  = ARRAY_SIZE(tuner_microtune_4049_fm5_params),
-       },
-       [TUNER_PANASONIC_VP27] = { /* Panasonic NTSC */
-               .name   = "Panasonic VP27s/ENGE4324D",
-               .params = tuner_panasonic_vp27_params,
-               .count  = ARRAY_SIZE(tuner_panasonic_vp27_params),
-       },
-       [TUNER_LG_NTSC_TAPE] = { /* LGINNOTEK NTSC */
-               .name   = "LG NTSC (TAPE series)",
-               .params = tuner_fm1236_mk3_params,
-               .count  = ARRAY_SIZE(tuner_fm1236_mk3_params),
-       },
-       [TUNER_TNF_8831BGFF] = { /* Philips PAL */
-               .name   = "Tenna TNF 8831 BGFF)",
-               .params = tuner_tnf_8831bgff_params,
-               .count  = ARRAY_SIZE(tuner_tnf_8831bgff_params),
-       },
-       [TUNER_MICROTUNE_4042FI5] = { /* Microtune NTSC */
-               .name   = "Microtune 4042 FI5 ATSC/NTSC dual in",
-               .params = tuner_microtune_4042fi5_params,
-               .count  = ARRAY_SIZE(tuner_microtune_4042fi5_params),
-               .min    = 16 *  57.00,
-               .max    = 16 * 858.00,
-               .stepsize = 62500,
-       },
-
-       /* 50-59 */
-       [TUNER_TCL_2002N] = { /* TCL NTSC */
-               .name   = "TCL 2002N",
-               .params = tuner_tcl_2002n_params,
-               .count  = ARRAY_SIZE(tuner_tcl_2002n_params),
-       },
-       [TUNER_PHILIPS_FM1256_IH3] = { /* Philips PAL */
-               .name   = "Philips PAL/SECAM_D (FM 1256 I-H3)",
-               .params = tuner_philips_fm1256_ih3_params,
-               .count  = ARRAY_SIZE(tuner_philips_fm1256_ih3_params),
-       },
-       [TUNER_THOMSON_DTT7610] = { /* THOMSON ATSC */
-               .name   = "Thomson DTT 7610 (ATSC/NTSC)",
-               .params = tuner_thomson_dtt7610_params,
-               .count  = ARRAY_SIZE(tuner_thomson_dtt7610_params),
-               .min    = 16 *  44.00,
-               .max    = 16 * 958.00,
-               .stepsize = 62500,
-       },
-       [TUNER_PHILIPS_FQ1286] = { /* Philips NTSC */
-               .name   = "Philips FQ1286",
-               .params = tuner_philips_fq1286_params,
-               .count  = ARRAY_SIZE(tuner_philips_fq1286_params),
-       },
-       [TUNER_PHILIPS_TDA8290] = { /* Philips PAL|NTSC */
-               .name   = "Philips/NXP TDA 8290/8295 + 8275/8275A/18271",
-               /* see tda8290.c for details */ },
-       [TUNER_TCL_2002MB] = { /* TCL PAL */
-               .name   = "TCL 2002MB",
-               .params = tuner_tcl_2002mb_params,
-               .count  = ARRAY_SIZE(tuner_tcl_2002mb_params),
-       },
-       [TUNER_PHILIPS_FQ1216AME_MK4] = { /* Philips PAL */
-               .name   = "Philips PAL/SECAM multi (FQ1216AME MK4)",
-               .params = tuner_philips_fq1216ame_mk4_params,
-               .count  = ARRAY_SIZE(tuner_philips_fq1216ame_mk4_params),
-       },
-       [TUNER_PHILIPS_FQ1236A_MK4] = { /* Philips NTSC */
-               .name   = "Philips FQ1236A MK4",
-               .params = tuner_philips_fq1236a_mk4_params,
-               .count  = ARRAY_SIZE(tuner_philips_fq1236a_mk4_params),
-       },
-       [TUNER_YMEC_TVF_8531MF] = { /* Philips NTSC */
-               .name   = "Ymec TVision TVF-8531MF/8831MF/8731MF",
-               .params = tuner_ymec_tvf_8531mf_params,
-               .count  = ARRAY_SIZE(tuner_ymec_tvf_8531mf_params),
-       },
-       [TUNER_YMEC_TVF_5533MF] = { /* Philips NTSC */
-               .name   = "Ymec TVision TVF-5533MF",
-               .params = tuner_ymec_tvf_5533mf_params,
-               .count  = ARRAY_SIZE(tuner_ymec_tvf_5533mf_params),
-       },
-
-       /* 60-69 */
-       [TUNER_THOMSON_DTT761X] = { /* THOMSON ATSC */
-               /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
-               .name   = "Thomson DTT 761X (ATSC/NTSC)",
-               .params = tuner_thomson_dtt761x_params,
-               .count  = ARRAY_SIZE(tuner_thomson_dtt761x_params),
-               .min    = 16 *  57.00,
-               .max    = 16 * 863.00,
-               .stepsize = 62500,
-               .initdata = tua603x_agc103,
-       },
-       [TUNER_TENA_9533_DI] = { /* Philips PAL */
-               .name   = "Tena TNF9533-D/IF/TNF9533-B/DF",
-               .params = tuner_tena_9533_di_params,
-               .count  = ARRAY_SIZE(tuner_tena_9533_di_params),
-       },
-       [TUNER_TEA5767] = { /* Philips RADIO */
-               .name   = "Philips TEA5767HN FM Radio",
-               /* see tea5767.c for details */
-       },
-       [TUNER_PHILIPS_FMD1216ME_MK3] = { /* Philips PAL */
-               .name   = "Philips FMD1216ME MK3 Hybrid Tuner",
-               .params = tuner_philips_fmd1216me_mk3_params,
-               .count  = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_params),
-               .min = 16 *  50.87,
-               .max = 16 * 858.00,
-               .stepsize = 166667,
-               .initdata = tua603x_agc112,
-               .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 },
-       },
-       [TUNER_LG_TDVS_H06XF] = { /* LGINNOTEK ATSC */
-               .name   = "LG TDVS-H06xF", /* H061F, H062F & H064F */
-               .params = tuner_lg_tdvs_h06xf_params,
-               .count  = ARRAY_SIZE(tuner_lg_tdvs_h06xf_params),
-               .min    = 16 *  54.00,
-               .max    = 16 * 863.00,
-               .stepsize = 62500,
-               .initdata = tua603x_agc103,
-       },
-       [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */
-               .name   = "Ymec TVF66T5-B/DFF",
-               .params = tuner_ymec_tvf66t5_b_dff_params,
-               .count  = ARRAY_SIZE(tuner_ymec_tvf66t5_b_dff_params),
-       },
-       [TUNER_LG_TALN] = { /* LGINNOTEK NTSC / PAL / SECAM */
-               .name   = "LG TALN series",
-               .params = tuner_lg_taln_params,
-               .count  = ARRAY_SIZE(tuner_lg_taln_params),
-       },
-       [TUNER_PHILIPS_TD1316] = { /* Philips PAL */
-               .name   = "Philips TD1316 Hybrid Tuner",
-               .params = tuner_philips_td1316_params,
-               .count  = ARRAY_SIZE(tuner_philips_td1316_params),
-               .min    = 16 *  87.00,
-               .max    = 16 * 895.00,
-               .stepsize = 166667,
-       },
-       [TUNER_PHILIPS_TUV1236D] = { /* Philips ATSC */
-               .name   = "Philips TUV1236D ATSC/NTSC dual in",
-               .params = tuner_tuv1236d_params,
-               .count  = ARRAY_SIZE(tuner_tuv1236d_params),
-               .min    = 16 *  54.00,
-               .max    = 16 * 864.00,
-               .stepsize = 62500,
-       },
-       [TUNER_TNF_5335MF] = { /* Tenna PAL/NTSC */
-               .name   = "Tena TNF 5335 and similar models",
-               .params = tuner_tnf_5335mf_params,
-               .count  = ARRAY_SIZE(tuner_tnf_5335mf_params),
-       },
-
-       /* 70-79 */
-       [TUNER_SAMSUNG_TCPN_2121P30A] = { /* Samsung NTSC */
-               .name   = "Samsung TCPN 2121P30A",
-               .params = tuner_samsung_tcpn_2121p30a_params,
-               .count  = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_params),
-       },
-       [TUNER_XC2028] = { /* Xceive 2028 */
-               .name   = "Xceive xc2028/xc3028 tuner",
-               /* see tuner-xc2028.c for details */
-       },
-       [TUNER_THOMSON_FE6600] = { /* Thomson PAL / DVB-T */
-               .name   = "Thomson FE6600",
-               .params = tuner_thomson_fe6600_params,
-               .count  = ARRAY_SIZE(tuner_thomson_fe6600_params),
-               .min    = 16 *  44.25,
-               .max    = 16 * 858.00,
-               .stepsize = 166667,
-       },
-       [TUNER_SAMSUNG_TCPG_6121P30A] = { /* Samsung PAL */
-               .name   = "Samsung TCPG 6121P30A",
-               .params = tuner_samsung_tcpg_6121p30a_params,
-               .count  = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_params),
-       },
-       [TUNER_TDA9887] = { /* Philips TDA 9887 IF PLL Demodulator.
-                               This chip is part of some modern tuners */
-               .name   = "Philips TDA988[5,6,7] IF PLL Demodulator",
-               /* see tda9887.c for details */
-       },
-       [TUNER_TEA5761] = { /* Philips RADIO */
-               .name   = "Philips TEA5761 FM Radio",
-               /* see tea5767.c for details */
-       },
-       [TUNER_XC5000] = { /* Xceive 5000 */
-               .name   = "Xceive 5000 tuner",
-               /* see xc5000.c for details */
-       },
-       [TUNER_XC4000] = { /* Xceive 4000 */
-               .name   = "Xceive 4000 tuner",
-               /* see xc4000.c for details */
-       },
-       [TUNER_TCL_MF02GIP_5N] = { /* TCL tuner MF02GIP-5N-E */
-               .name   = "TCL tuner MF02GIP-5N-E",
-               .params = tuner_tcl_mf02gip_5n_params,
-               .count  = ARRAY_SIZE(tuner_tcl_mf02gip_5n_params),
-       },
-       [TUNER_PHILIPS_FMD1216MEX_MK3] = { /* Philips PAL */
-               .name   = "Philips FMD1216MEX MK3 Hybrid Tuner",
-               .params = tuner_philips_fmd1216mex_mk3_params,
-               .count  = ARRAY_SIZE(tuner_philips_fmd1216mex_mk3_params),
-               .min = 16 *  50.87,
-               .max = 16 * 858.00,
-               .stepsize = 166667,
-               .initdata = tua603x_agc112,
-               .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 },
-       },
-               [TUNER_PHILIPS_FM1216MK5] = { /* Philips PAL */
-               .name   = "Philips PAL/SECAM multi (FM1216 MK5)",
-               .params = tuner_fm1216mk5_params,
-               .count  = ARRAY_SIZE(tuner_fm1216mk5_params),
-       },
-
-       /* 80-89 */
-       [TUNER_PHILIPS_FQ1216LME_MK3] = { /* PAL/SECAM, Loop-thru, no FM */
-               .name = "Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough",
-               .params = tuner_fq1216lme_mk3_params,
-               .count  = ARRAY_SIZE(tuner_fq1216lme_mk3_params),
-       },
-
-       [TUNER_PARTSNIC_PTI_5NF05] = {
-               .name = "Partsnic (Daewoo) PTI-5NF05",
-               .params = tuner_partsnic_pti_5nf05_params,
-               .count  = ARRAY_SIZE(tuner_partsnic_pti_5nf05_params),
-       },
-       [TUNER_PHILIPS_CU1216L] = {
-               .name = "Philips CU1216L",
-               .params = tuner_philips_cu1216l_params,
-               .count  = ARRAY_SIZE(tuner_philips_cu1216l_params),
-               .stepsize = 62500,
-       },
-       [TUNER_NXP_TDA18271] = {
-               .name   = "NXP TDA18271",
-               /* see tda18271-fe.c for details */
-       },
-       [TUNER_SONY_BTF_PXN01Z] = {
-               .name   = "Sony BTF-Pxn01Z",
-               .params = tuner_sony_btf_pxn01z_params,
-               .count  = ARRAY_SIZE(tuner_sony_btf_pxn01z_params),
-       },
-       [TUNER_PHILIPS_FQ1236_MK5] = { /* NTSC, TDA9885, no FM radio */
-               .name   = "Philips FQ1236 MK5",
-               .params = tuner_philips_fq1236_mk5_params,
-               .count  = ARRAY_SIZE(tuner_philips_fq1236_mk5_params),
-       },
-       [TUNER_TENA_TNF_5337] = { /* Tena 5337 MFD */
-               .name   = "Tena TNF5337 MFD",
-               .params = tuner_tena_tnf_5337_params,
-               .count  = ARRAY_SIZE(tuner_tena_tnf_5337_params),
-       },
-       [TUNER_XC5000C] = { /* Xceive 5000C */
-               .name   = "Xceive 5000C tuner",
-               /* see xc5000.c for details */
-       },
-};
-EXPORT_SYMBOL(tuners);
-
-unsigned const int tuner_count = ARRAY_SIZE(tuners);
-EXPORT_SYMBOL(tuner_count);
-
-MODULE_DESCRIPTION("Simple tuner device type database");
-MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/tuner-xc2028-types.h b/drivers/media/common/tuners/tuner-xc2028-types.h
deleted file mode 100644 (file)
index 74dc46a..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/* tuner-xc2028_types
- *
- * This file includes internal tipes to be used inside tuner-xc2028.
- * Shouldn't be included outside tuner-xc2028
- *
- * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNU General Public License v2
- */
-
-/* xc3028 firmware types */
-
-/* BASE firmware should be loaded before any other firmware */
-#define BASE           (1<<0)
-#define BASE_TYPES     (BASE|F8MHZ|MTS|FM|INPUT1|INPUT2|INIT1)
-
-/* F8MHZ marks BASE firmwares for 8 MHz Bandwidth */
-#define F8MHZ          (1<<1)
-
-/* Multichannel Television Sound (MTS)
-   Those firmwares are capable of using xc2038 DSP to decode audio and
-   produce a baseband audio output on some pins of the chip.
-   There are MTS firmwares for the most used video standards. It should be
-   required to use MTS firmwares, depending on the way audio is routed into
-   the bridge chip
- */
-#define MTS            (1<<2)
-
-/* FIXME: I have no idea what's the difference between
-   D2620 and D2633 firmwares
- */
-#define D2620          (1<<3)
-#define D2633          (1<<4)
-
-/* DTV firmwares for 6, 7 and 8 MHz
-   DTV6 - 6MHz - ATSC/DVB-C/DVB-T/ISDB-T/DOCSIS
-   DTV8 - 8MHz - DVB-C/DVB-T
- */
-#define DTV6           (1 << 5)
-#define QAM            (1 << 6)
-#define DTV7           (1<<7)
-#define DTV78          (1<<8)
-#define DTV8           (1<<9)
-
-#define DTV_TYPES      (D2620|D2633|DTV6|QAM|DTV7|DTV78|DTV8|ATSC)
-
-/* There's a FM | BASE firmware + FM specific firmware (std=0) */
-#define        FM              (1<<10)
-
-#define STD_SPECIFIC_TYPES (MTS|FM|LCD|NOGD)
-
-/* Applies only for FM firmware
-   Makes it use RF input 1 (pin #2) instead of input 2 (pin #4)
- */
-#define INPUT1         (1<<11)
-
-
-/* LCD firmwares exist only for MTS STD/MN (PAL or NTSC/M)
-       and for non-MTS STD/MN (PAL, NTSC/M or NTSC/Kr)
-       There are variants both with and without NOGD
-       Those firmwares produce better result with LCD displays
- */
-#define LCD            (1<<12)
-
-/* NOGD firmwares exist only for MTS STD/MN (PAL or NTSC/M)
-       and for non-MTS STD/MN (PAL, NTSC/M or NTSC/Kr)
-       The NOGD firmwares don't have group delay compensation filter
- */
-#define NOGD           (1<<13)
-
-/* Old firmwares were broken into init0 and init1 */
-#define INIT1          (1<<14)
-
-/* SCODE firmware selects particular behaviours */
-#define MONO           (1 << 15)
-#define ATSC           (1 << 16)
-#define IF             (1 << 17)
-#define LG60           (1 << 18)
-#define ATI638         (1 << 19)
-#define OREN538        (1 << 20)
-#define OREN36         (1 << 21)
-#define TOYOTA388      (1 << 22)
-#define TOYOTA794      (1 << 23)
-#define DIBCOM52       (1 << 24)
-#define ZARLINK456     (1 << 25)
-#define CHINA          (1 << 26)
-#define F6MHZ          (1 << 27)
-#define INPUT2         (1 << 28)
-#define SCODE          (1 << 29)
-
-/* This flag identifies that the scode table has a new format */
-#define HAS_IF         (1 << 30)
-
-/* There are different scode tables for MTS and non-MTS.
-   The MTS firmwares support mono only
-  */
-#define SCODE_TYPES (SCODE | MTS)
-
-
-/* Newer types not defined on videodev2.h.
-   The original idea were to move all those types to videodev2.h, but
-   it seemed overkill, since, with the exception of SECAM/K3, the other
-   types seem to be autodetected.
-   It is not clear where secam/k3 is used, nor we have a feedback of this
-   working or being autodetected by the standard secam firmware.
- */
-
-#define V4L2_STD_SECAM_K3      (0x04000000)
-
-/* Audio types */
-
-#define V4L2_STD_A2_A          (1LL<<32)
-#define V4L2_STD_A2_B          (1LL<<33)
-#define V4L2_STD_NICAM_A       (1LL<<34)
-#define V4L2_STD_NICAM_B       (1LL<<35)
-#define V4L2_STD_AM            (1LL<<36)
-#define V4L2_STD_BTSC          (1LL<<37)
-#define V4L2_STD_EIAJ          (1LL<<38)
-
-#define V4L2_STD_A2            (V4L2_STD_A2_A    | V4L2_STD_A2_B)
-#define V4L2_STD_NICAM         (V4L2_STD_NICAM_A | V4L2_STD_NICAM_B)
-
-/* To preserve backward compatibilty,
-   (std & V4L2_STD_AUDIO) = 0 means that ALL audio stds are supported
- */
-
-#define V4L2_STD_AUDIO         (V4L2_STD_A2    | \
-                                V4L2_STD_NICAM | \
-                                V4L2_STD_AM    | \
-                                V4L2_STD_BTSC  | \
-                                V4L2_STD_EIAJ)
-
-/* Used standards with audio restrictions */
-
-#define V4L2_STD_PAL_BG_A2_A   (V4L2_STD_PAL_BG | V4L2_STD_A2_A)
-#define V4L2_STD_PAL_BG_A2_B   (V4L2_STD_PAL_BG | V4L2_STD_A2_B)
-#define V4L2_STD_PAL_BG_NICAM_A        (V4L2_STD_PAL_BG | V4L2_STD_NICAM_A)
-#define V4L2_STD_PAL_BG_NICAM_B        (V4L2_STD_PAL_BG | V4L2_STD_NICAM_B)
-#define V4L2_STD_PAL_DK_A2     (V4L2_STD_PAL_DK | V4L2_STD_A2)
-#define V4L2_STD_PAL_DK_NICAM  (V4L2_STD_PAL_DK | V4L2_STD_NICAM)
-#define V4L2_STD_SECAM_L_NICAM (V4L2_STD_SECAM_L | V4L2_STD_NICAM)
-#define V4L2_STD_SECAM_L_AM    (V4L2_STD_SECAM_L | V4L2_STD_AM)
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
deleted file mode 100644 (file)
index 7bcb6b0..0000000
+++ /dev/null
@@ -1,1509 +0,0 @@
-/* tuner-xc2028
- *
- * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
- *
- * Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com)
- *       - frontend interface
- *
- * This code is placed under the terms of the GNU General Public License v2
- */
-
-#include <linux/i2c.h>
-#include <asm/div64.h>
-#include <linux/firmware.h>
-#include <linux/videodev2.h>
-#include <linux/delay.h>
-#include <media/tuner.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <asm/unaligned.h>
-#include "tuner-i2c.h"
-#include "tuner-xc2028.h"
-#include "tuner-xc2028-types.h"
-
-#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
-
-/* Registers (Write-only) */
-#define XREG_INIT         0x00
-#define XREG_RF_FREQ      0x02
-#define XREG_POWER_DOWN   0x08
-
-/* Registers (Read-only) */
-#define XREG_FREQ_ERROR   0x01
-#define XREG_LOCK         0x02
-#define XREG_VERSION      0x04
-#define XREG_PRODUCT_ID   0x08
-#define XREG_HSYNC_FREQ   0x10
-#define XREG_FRAME_LINES  0x20
-#define XREG_SNR          0x40
-
-#define XREG_ADC_ENV      0x0100
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable verbose debug messages");
-
-static int no_poweroff;
-module_param(no_poweroff, int, 0644);
-MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n"
-       "1 keep device energized and with tuner ready all the times.\n"
-       "  Faster, but consumes more power and keeps the device hotter\n");
-
-static char audio_std[8];
-module_param_string(audio_std, audio_std, sizeof(audio_std), 0);
-MODULE_PARM_DESC(audio_std,
-       "Audio standard. XC3028 audio decoder explicitly "
-       "needs to know what audio\n"
-       "standard is needed for some video standards with audio A2 or NICAM.\n"
-       "The valid values are:\n"
-       "A2\n"
-       "A2/A\n"
-       "A2/B\n"
-       "NICAM\n"
-       "NICAM/A\n"
-       "NICAM/B\n");
-
-static char firmware_name[30];
-module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0);
-MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the "
-                               "default firmware name\n");
-
-static LIST_HEAD(hybrid_tuner_instance_list);
-static DEFINE_MUTEX(xc2028_list_mutex);
-
-/* struct for storing firmware table */
-struct firmware_description {
-       unsigned int  type;
-       v4l2_std_id   id;
-       __u16         int_freq;
-       unsigned char *ptr;
-       unsigned int  size;
-};
-
-struct firmware_properties {
-       unsigned int    type;
-       v4l2_std_id     id;
-       v4l2_std_id     std_req;
-       __u16           int_freq;
-       unsigned int    scode_table;
-       int             scode_nr;
-};
-
-enum xc2028_state {
-       XC2028_NO_FIRMWARE = 0,
-       XC2028_WAITING_FIRMWARE,
-       XC2028_ACTIVE,
-       XC2028_SLEEP,
-       XC2028_NODEV,
-};
-
-struct xc2028_data {
-       struct list_head        hybrid_tuner_instance_list;
-       struct tuner_i2c_props  i2c_props;
-       __u32                   frequency;
-
-       enum xc2028_state       state;
-       const char              *fname;
-
-       struct firmware_description *firm;
-       int                     firm_size;
-       __u16                   firm_version;
-
-       __u16                   hwmodel;
-       __u16                   hwvers;
-
-       struct xc2028_ctrl      ctrl;
-
-       struct firmware_properties cur_fw;
-
-       struct mutex lock;
-};
-
-#define i2c_send(priv, buf, size) ({                                   \
-       int _rc;                                                        \
-       _rc = tuner_i2c_xfer_send(&priv->i2c_props, buf, size);         \
-       if (size != _rc)                                                \
-               tuner_info("i2c output error: rc = %d (should be %d)\n",\
-                          _rc, (int)size);                             \
-       if (priv->ctrl.msleep)                                          \
-               msleep(priv->ctrl.msleep);                              \
-       _rc;                                                            \
-})
-
-#define i2c_rcv(priv, buf, size) ({                                    \
-       int _rc;                                                        \
-       _rc = tuner_i2c_xfer_recv(&priv->i2c_props, buf, size);         \
-       if (size != _rc)                                                \
-               tuner_err("i2c input error: rc = %d (should be %d)\n",  \
-                          _rc, (int)size);                             \
-       _rc;                                                            \
-})
-
-#define i2c_send_recv(priv, obuf, osize, ibuf, isize) ({               \
-       int _rc;                                                        \
-       _rc = tuner_i2c_xfer_send_recv(&priv->i2c_props, obuf, osize,   \
-                                      ibuf, isize);                    \
-       if (isize != _rc)                                               \
-               tuner_err("i2c input error: rc = %d (should be %d)\n",  \
-                          _rc, (int)isize);                            \
-       if (priv->ctrl.msleep)                                          \
-               msleep(priv->ctrl.msleep);                              \
-       _rc;                                                            \
-})
-
-#define send_seq(priv, data...)        ({                                      \
-       static u8 _val[] = data;                                        \
-       int _rc;                                                        \
-       if (sizeof(_val) !=                                             \
-                       (_rc = tuner_i2c_xfer_send(&priv->i2c_props,    \
-                                               _val, sizeof(_val)))) { \
-               tuner_err("Error on line %d: %d\n", __LINE__, _rc);     \
-       } else if (priv->ctrl.msleep)                                   \
-               msleep(priv->ctrl.msleep);                              \
-       _rc;                                                            \
-})
-
-static int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val)
-{
-       unsigned char buf[2];
-       unsigned char ibuf[2];
-
-       tuner_dbg("%s %04x called\n", __func__, reg);
-
-       buf[0] = reg >> 8;
-       buf[1] = (unsigned char) reg;
-
-       if (i2c_send_recv(priv, buf, 2, ibuf, 2) != 2)
-               return -EIO;
-
-       *val = (ibuf[1]) | (ibuf[0] << 8);
-       return 0;
-}
-
-#define dump_firm_type(t)      dump_firm_type_and_int_freq(t, 0)
-static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
-{
-        if (type & BASE)
-               printk("BASE ");
-        if (type & INIT1)
-               printk("INIT1 ");
-        if (type & F8MHZ)
-               printk("F8MHZ ");
-        if (type & MTS)
-               printk("MTS ");
-        if (type & D2620)
-               printk("D2620 ");
-        if (type & D2633)
-               printk("D2633 ");
-        if (type & DTV6)
-               printk("DTV6 ");
-        if (type & QAM)
-               printk("QAM ");
-        if (type & DTV7)
-               printk("DTV7 ");
-        if (type & DTV78)
-               printk("DTV78 ");
-        if (type & DTV8)
-               printk("DTV8 ");
-        if (type & FM)
-               printk("FM ");
-        if (type & INPUT1)
-               printk("INPUT1 ");
-        if (type & LCD)
-               printk("LCD ");
-        if (type & NOGD)
-               printk("NOGD ");
-        if (type & MONO)
-               printk("MONO ");
-        if (type & ATSC)
-               printk("ATSC ");
-        if (type & IF)
-               printk("IF ");
-        if (type & LG60)
-               printk("LG60 ");
-        if (type & ATI638)
-               printk("ATI638 ");
-        if (type & OREN538)
-               printk("OREN538 ");
-        if (type & OREN36)
-               printk("OREN36 ");
-        if (type & TOYOTA388)
-               printk("TOYOTA388 ");
-        if (type & TOYOTA794)
-               printk("TOYOTA794 ");
-        if (type & DIBCOM52)
-               printk("DIBCOM52 ");
-        if (type & ZARLINK456)
-               printk("ZARLINK456 ");
-        if (type & CHINA)
-               printk("CHINA ");
-        if (type & F6MHZ)
-               printk("F6MHZ ");
-        if (type & INPUT2)
-               printk("INPUT2 ");
-        if (type & SCODE)
-               printk("SCODE ");
-        if (type & HAS_IF)
-               printk("HAS_IF_%d ", int_freq);
-}
-
-static  v4l2_std_id parse_audio_std_option(void)
-{
-       if (strcasecmp(audio_std, "A2") == 0)
-               return V4L2_STD_A2;
-       if (strcasecmp(audio_std, "A2/A") == 0)
-               return V4L2_STD_A2_A;
-       if (strcasecmp(audio_std, "A2/B") == 0)
-               return V4L2_STD_A2_B;
-       if (strcasecmp(audio_std, "NICAM") == 0)
-               return V4L2_STD_NICAM;
-       if (strcasecmp(audio_std, "NICAM/A") == 0)
-               return V4L2_STD_NICAM_A;
-       if (strcasecmp(audio_std, "NICAM/B") == 0)
-               return V4L2_STD_NICAM_B;
-
-       return 0;
-}
-
-static int check_device_status(struct xc2028_data *priv)
-{
-       switch (priv->state) {
-       case XC2028_NO_FIRMWARE:
-       case XC2028_WAITING_FIRMWARE:
-               return -EAGAIN;
-       case XC2028_ACTIVE:
-       case XC2028_SLEEP:
-               return 0;
-       case XC2028_NODEV:
-               return -ENODEV;
-       }
-       return 0;
-}
-
-static void free_firmware(struct xc2028_data *priv)
-{
-       int i;
-       tuner_dbg("%s called\n", __func__);
-
-       if (!priv->firm)
-               return;
-
-       for (i = 0; i < priv->firm_size; i++)
-               kfree(priv->firm[i].ptr);
-
-       kfree(priv->firm);
-
-       priv->firm = NULL;
-       priv->firm_size = 0;
-       priv->state = XC2028_NO_FIRMWARE;
-
-       memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
-}
-
-static int load_all_firmwares(struct dvb_frontend *fe,
-                             const struct firmware *fw)
-{
-       struct xc2028_data    *priv = fe->tuner_priv;
-       const unsigned char   *p, *endp;
-       int                   rc = 0;
-       int                   n, n_array;
-       char                  name[33];
-
-       tuner_dbg("%s called\n", __func__);
-
-       p = fw->data;
-       endp = p + fw->size;
-
-       if (fw->size < sizeof(name) - 1 + 2 + 2) {
-               tuner_err("Error: firmware file %s has invalid size!\n",
-                         priv->fname);
-               goto corrupt;
-       }
-
-       memcpy(name, p, sizeof(name) - 1);
-       name[sizeof(name) - 1] = 0;
-       p += sizeof(name) - 1;
-
-       priv->firm_version = get_unaligned_le16(p);
-       p += 2;
-
-       n_array = get_unaligned_le16(p);
-       p += 2;
-
-       tuner_info("Loading %d firmware images from %s, type: %s, ver %d.%d\n",
-                  n_array, priv->fname, name,
-                  priv->firm_version >> 8, priv->firm_version & 0xff);
-
-       priv->firm = kcalloc(n_array, sizeof(*priv->firm), GFP_KERNEL);
-       if (priv->firm == NULL) {
-               tuner_err("Not enough memory to load firmware file.\n");
-               rc = -ENOMEM;
-               goto err;
-       }
-       priv->firm_size = n_array;
-
-       n = -1;
-       while (p < endp) {
-               __u32 type, size;
-               v4l2_std_id id;
-               __u16 int_freq = 0;
-
-               n++;
-               if (n >= n_array) {
-                       tuner_err("More firmware images in file than "
-                                 "were expected!\n");
-                       goto corrupt;
-               }
-
-               /* Checks if there's enough bytes to read */
-               if (endp - p < sizeof(type) + sizeof(id) + sizeof(size))
-                       goto header;
-
-               type = get_unaligned_le32(p);
-               p += sizeof(type);
-
-               id = get_unaligned_le64(p);
-               p += sizeof(id);
-
-               if (type & HAS_IF) {
-                       int_freq = get_unaligned_le16(p);
-                       p += sizeof(int_freq);
-                       if (endp - p < sizeof(size))
-                               goto header;
-               }
-
-               size = get_unaligned_le32(p);
-               p += sizeof(size);
-
-               if (!size || size > endp - p) {
-                       tuner_err("Firmware type ");
-                       dump_firm_type(type);
-                       printk("(%x), id %llx is corrupted "
-                              "(size=%d, expected %d)\n",
-                              type, (unsigned long long)id,
-                              (unsigned)(endp - p), size);
-                       goto corrupt;
-               }
-
-               priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
-               if (priv->firm[n].ptr == NULL) {
-                       tuner_err("Not enough memory to load firmware file.\n");
-                       rc = -ENOMEM;
-                       goto err;
-               }
-               tuner_dbg("Reading firmware type ");
-               if (debug) {
-                       dump_firm_type_and_int_freq(type, int_freq);
-                       printk("(%x), id %llx, size=%d.\n",
-                              type, (unsigned long long)id, size);
-               }
-
-               memcpy(priv->firm[n].ptr, p, size);
-               priv->firm[n].type = type;
-               priv->firm[n].id   = id;
-               priv->firm[n].size = size;
-               priv->firm[n].int_freq = int_freq;
-
-               p += size;
-       }
-
-       if (n + 1 != priv->firm_size) {
-               tuner_err("Firmware file is incomplete!\n");
-               goto corrupt;
-       }
-
-       goto done;
-
-header:
-       tuner_err("Firmware header is incomplete!\n");
-corrupt:
-       rc = -EINVAL;
-       tuner_err("Error: firmware file is corrupted!\n");
-
-err:
-       tuner_info("Releasing partially loaded firmware file.\n");
-       free_firmware(priv);
-
-done:
-       if (rc == 0)
-               tuner_dbg("Firmware files loaded.\n");
-       else
-               priv->state = XC2028_NODEV;
-
-       return rc;
-}
-
-static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
-                        v4l2_std_id *id)
-{
-       struct xc2028_data *priv = fe->tuner_priv;
-       int                 i, best_i = -1, best_nr_matches = 0;
-       unsigned int        type_mask = 0;
-
-       tuner_dbg("%s called, want type=", __func__);
-       if (debug) {
-               dump_firm_type(type);
-               printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
-       }
-
-       if (!priv->firm) {
-               tuner_err("Error! firmware not loaded\n");
-               return -EINVAL;
-       }
-
-       if (((type & ~SCODE) == 0) && (*id == 0))
-               *id = V4L2_STD_PAL;
-
-       if (type & BASE)
-               type_mask = BASE_TYPES;
-       else if (type & SCODE) {
-               type &= SCODE_TYPES;
-               type_mask = SCODE_TYPES & ~HAS_IF;
-       } else if (type & DTV_TYPES)
-               type_mask = DTV_TYPES;
-       else if (type & STD_SPECIFIC_TYPES)
-               type_mask = STD_SPECIFIC_TYPES;
-
-       type &= type_mask;
-
-       if (!(type & SCODE))
-               type_mask = ~0;
-
-       /* Seek for exact match */
-       for (i = 0; i < priv->firm_size; i++) {
-               if ((type == (priv->firm[i].type & type_mask)) &&
-                   (*id == priv->firm[i].id))
-                       goto found;
-       }
-
-       /* Seek for generic video standard match */
-       for (i = 0; i < priv->firm_size; i++) {
-               v4l2_std_id match_mask;
-               int nr_matches;
-
-               if (type != (priv->firm[i].type & type_mask))
-                       continue;
-
-               match_mask = *id & priv->firm[i].id;
-               if (!match_mask)
-                       continue;
-
-               if ((*id & match_mask) == *id)
-                       goto found; /* Supports all the requested standards */
-
-               nr_matches = hweight64(match_mask);
-               if (nr_matches > best_nr_matches) {
-                       best_nr_matches = nr_matches;
-                       best_i = i;
-               }
-       }
-
-       if (best_nr_matches > 0) {
-               tuner_dbg("Selecting best matching firmware (%d bits) for "
-                         "type=", best_nr_matches);
-               dump_firm_type(type);
-               printk("(%x), id %016llx:\n", type, (unsigned long long)*id);
-               i = best_i;
-               goto found;
-       }
-
-       /*FIXME: Would make sense to seek for type "hint" match ? */
-
-       i = -ENOENT;
-       goto ret;
-
-found:
-       *id = priv->firm[i].id;
-
-ret:
-       tuner_dbg("%s firmware for type=", (i < 0) ? "Can't find" : "Found");
-       if (debug) {
-               dump_firm_type(type);
-               printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
-       }
-       return i;
-}
-
-static inline int do_tuner_callback(struct dvb_frontend *fe, int cmd, int arg)
-{
-       struct xc2028_data *priv = fe->tuner_priv;
-
-       /* analog side (tuner-core) uses i2c_adap->algo_data.
-        * digital side is not guaranteed to have algo_data defined.
-        *
-        * digital side will always have fe->dvb defined.
-        * analog side (tuner-core) doesn't (yet) define fe->dvb.
-        */
-
-       return (!fe->callback) ? -EINVAL :
-               fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
-                               fe->dvb->priv : priv->i2c_props.adap->algo_data,
-                            DVB_FRONTEND_COMPONENT_TUNER, cmd, arg);
-}
-
-static int load_firmware(struct dvb_frontend *fe, unsigned int type,
-                        v4l2_std_id *id)
-{
-       struct xc2028_data *priv = fe->tuner_priv;
-       int                pos, rc;
-       unsigned char      *p, *endp, buf[priv->ctrl.max_len];
-
-       tuner_dbg("%s called\n", __func__);
-
-       pos = seek_firmware(fe, type, id);
-       if (pos < 0)
-               return pos;
-
-       tuner_info("Loading firmware for type=");
-       dump_firm_type(priv->firm[pos].type);
-       printk("(%x), id %016llx.\n", priv->firm[pos].type,
-              (unsigned long long)*id);
-
-       p = priv->firm[pos].ptr;
-       endp = p + priv->firm[pos].size;
-
-       while (p < endp) {
-               __u16 size;
-
-               /* Checks if there's enough bytes to read */
-               if (p + sizeof(size) > endp) {
-                       tuner_err("Firmware chunk size is wrong\n");
-                       return -EINVAL;
-               }
-
-               size = le16_to_cpu(*(__u16 *) p);
-               p += sizeof(size);
-
-               if (size == 0xffff)
-                       return 0;
-
-               if (!size) {
-                       /* Special callback command received */
-                       rc = do_tuner_callback(fe, XC2028_TUNER_RESET, 0);
-                       if (rc < 0) {
-                               tuner_err("Error at RESET code %d\n",
-                                          (*p) & 0x7f);
-                               return -EINVAL;
-                       }
-                       continue;
-               }
-               if (size >= 0xff00) {
-                       switch (size) {
-                       case 0xff00:
-                               rc = do_tuner_callback(fe, XC2028_RESET_CLK, 0);
-                               if (rc < 0) {
-                                       tuner_err("Error at RESET code %d\n",
-                                                 (*p) & 0x7f);
-                                       return -EINVAL;
-                               }
-                               break;
-                       default:
-                               tuner_info("Invalid RESET code %d\n",
-                                          size & 0x7f);
-                               return -EINVAL;
-
-                       }
-                       continue;
-               }
-
-               /* Checks for a sleep command */
-               if (size & 0x8000) {
-                       msleep(size & 0x7fff);
-                       continue;
-               }
-
-               if ((size + p > endp)) {
-                       tuner_err("missing bytes: need %d, have %d\n",
-                                  size, (int)(endp - p));
-                       return -EINVAL;
-               }
-
-               buf[0] = *p;
-               p++;
-               size--;
-
-               /* Sends message chunks */
-               while (size > 0) {
-                       int len = (size < priv->ctrl.max_len - 1) ?
-                                  size : priv->ctrl.max_len - 1;
-
-                       memcpy(buf + 1, p, len);
-
-                       rc = i2c_send(priv, buf, len + 1);
-                       if (rc < 0) {
-                               tuner_err("%d returned from send\n", rc);
-                               return -EINVAL;
-                       }
-
-                       p += len;
-                       size -= len;
-               }
-
-               /* silently fail if the frontend doesn't support I2C flush */
-               rc = do_tuner_callback(fe, XC2028_I2C_FLUSH, 0);
-               if ((rc < 0) && (rc != -EINVAL)) {
-                       tuner_err("error executing flush: %d\n", rc);
-                       return rc;
-               }
-       }
-       return 0;
-}
-
-static int load_scode(struct dvb_frontend *fe, unsigned int type,
-                        v4l2_std_id *id, __u16 int_freq, int scode)
-{
-       struct xc2028_data *priv = fe->tuner_priv;
-       int                pos, rc;
-       unsigned char      *p;
-
-       tuner_dbg("%s called\n", __func__);
-
-       if (!int_freq) {
-               pos = seek_firmware(fe, type, id);
-               if (pos < 0)
-                       return pos;
-       } else {
-               for (pos = 0; pos < priv->firm_size; pos++) {
-                       if ((priv->firm[pos].int_freq == int_freq) &&
-                           (priv->firm[pos].type & HAS_IF))
-                               break;
-               }
-               if (pos == priv->firm_size)
-                       return -ENOENT;
-       }
-
-       p = priv->firm[pos].ptr;
-
-       if (priv->firm[pos].type & HAS_IF) {
-               if (priv->firm[pos].size != 12 * 16 || scode >= 16)
-                       return -EINVAL;
-               p += 12 * scode;
-       } else {
-               /* 16 SCODE entries per file; each SCODE entry is 12 bytes and
-                * has a 2-byte size header in the firmware format. */
-               if (priv->firm[pos].size != 14 * 16 || scode >= 16 ||
-                   le16_to_cpu(*(__u16 *)(p + 14 * scode)) != 12)
-                       return -EINVAL;
-               p += 14 * scode + 2;
-       }
-
-       tuner_info("Loading SCODE for type=");
-       dump_firm_type_and_int_freq(priv->firm[pos].type,
-                                   priv->firm[pos].int_freq);
-       printk("(%x), id %016llx.\n", priv->firm[pos].type,
-              (unsigned long long)*id);
-
-       if (priv->firm_version < 0x0202)
-               rc = send_seq(priv, {0x20, 0x00, 0x00, 0x00});
-       else
-               rc = send_seq(priv, {0xa0, 0x00, 0x00, 0x00});
-       if (rc < 0)
-               return -EIO;
-
-       rc = i2c_send(priv, p, 12);
-       if (rc < 0)
-               return -EIO;
-
-       rc = send_seq(priv, {0x00, 0x8c});
-       if (rc < 0)
-               return -EIO;
-
-       return 0;
-}
-
-static int check_firmware(struct dvb_frontend *fe, unsigned int type,
-                         v4l2_std_id std, __u16 int_freq)
-{
-       struct xc2028_data         *priv = fe->tuner_priv;
-       struct firmware_properties new_fw;
-       int                        rc, retry_count = 0;
-       u16                        version, hwmodel;
-       v4l2_std_id                std0;
-
-       tuner_dbg("%s called\n", __func__);
-
-       rc = check_device_status(priv);
-       if (rc < 0)
-               return rc;
-
-       if (priv->ctrl.mts && !(type & FM))
-               type |= MTS;
-
-retry:
-       new_fw.type = type;
-       new_fw.id = std;
-       new_fw.std_req = std;
-       new_fw.scode_table = SCODE | priv->ctrl.scode_table;
-       new_fw.scode_nr = 0;
-       new_fw.int_freq = int_freq;
-
-       tuner_dbg("checking firmware, user requested type=");
-       if (debug) {
-               dump_firm_type(new_fw.type);
-               printk("(%x), id %016llx, ", new_fw.type,
-                      (unsigned long long)new_fw.std_req);
-               if (!int_freq) {
-                       printk("scode_tbl ");
-                       dump_firm_type(priv->ctrl.scode_table);
-                       printk("(%x), ", priv->ctrl.scode_table);
-               } else
-                       printk("int_freq %d, ", new_fw.int_freq);
-               printk("scode_nr %d\n", new_fw.scode_nr);
-       }
-
-       /*
-        * No need to reload base firmware if it matches and if the tuner
-        * is not at sleep mode
-        */
-       if ((priv->state == XC2028_ACTIVE) &&
-           (((BASE | new_fw.type) & BASE_TYPES) ==
-           (priv->cur_fw.type & BASE_TYPES))) {
-               tuner_dbg("BASE firmware not changed.\n");
-               goto skip_base;
-       }
-
-       /* Updating BASE - forget about all currently loaded firmware */
-       memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
-
-       /* Reset is needed before loading firmware */
-       rc = do_tuner_callback(fe, XC2028_TUNER_RESET, 0);
-       if (rc < 0)
-               goto fail;
-
-       /* BASE firmwares are all std0 */
-       std0 = 0;
-       rc = load_firmware(fe, BASE | new_fw.type, &std0);
-       if (rc < 0) {
-               tuner_err("Error %d while loading base firmware\n",
-                         rc);
-               goto fail;
-       }
-
-       /* Load INIT1, if needed */
-       tuner_dbg("Load init1 firmware, if exists\n");
-
-       rc = load_firmware(fe, BASE | INIT1 | new_fw.type, &std0);
-       if (rc == -ENOENT)
-               rc = load_firmware(fe, (BASE | INIT1 | new_fw.type) & ~F8MHZ,
-                                  &std0);
-       if (rc < 0 && rc != -ENOENT) {
-               tuner_err("Error %d while loading init1 firmware\n",
-                         rc);
-               goto fail;
-       }
-
-skip_base:
-       /*
-        * No need to reload standard specific firmware if base firmware
-        * was not reloaded and requested video standards have not changed.
-        */
-       if (priv->cur_fw.type == (BASE | new_fw.type) &&
-           priv->cur_fw.std_req == std) {
-               tuner_dbg("Std-specific firmware already loaded.\n");
-               goto skip_std_specific;
-       }
-
-       /* Reloading std-specific firmware forces a SCODE update */
-       priv->cur_fw.scode_table = 0;
-
-       rc = load_firmware(fe, new_fw.type, &new_fw.id);
-       if (rc == -ENOENT)
-               rc = load_firmware(fe, new_fw.type & ~F8MHZ, &new_fw.id);
-
-       if (rc < 0)
-               goto fail;
-
-skip_std_specific:
-       if (priv->cur_fw.scode_table == new_fw.scode_table &&
-           priv->cur_fw.scode_nr == new_fw.scode_nr) {
-               tuner_dbg("SCODE firmware already loaded.\n");
-               goto check_device;
-       }
-
-       if (new_fw.type & FM)
-               goto check_device;
-
-       /* Load SCODE firmware, if exists */
-       tuner_dbg("Trying to load scode %d\n", new_fw.scode_nr);
-
-       rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id,
-                       new_fw.int_freq, new_fw.scode_nr);
-
-check_device:
-       if (xc2028_get_reg(priv, 0x0004, &version) < 0 ||
-           xc2028_get_reg(priv, 0x0008, &hwmodel) < 0) {
-               tuner_err("Unable to read tuner registers.\n");
-               goto fail;
-       }
-
-       tuner_dbg("Device is Xceive %d version %d.%d, "
-                 "firmware version %d.%d\n",
-                 hwmodel, (version & 0xf000) >> 12, (version & 0xf00) >> 8,
-                 (version & 0xf0) >> 4, version & 0xf);
-
-
-       if (priv->ctrl.read_not_reliable)
-               goto read_not_reliable;
-
-       /* Check firmware version against what we downloaded. */
-       if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) {
-               if (!priv->ctrl.read_not_reliable) {
-                       tuner_err("Incorrect readback of firmware version.\n");
-                       goto fail;
-               } else {
-                       tuner_err("Returned an incorrect version. However, "
-                                 "read is not reliable enough. Ignoring it.\n");
-                       hwmodel = 3028;
-               }
-       }
-
-       /* Check that the tuner hardware model remains consistent over time. */
-       if (priv->hwmodel == 0 && (hwmodel == 2028 || hwmodel == 3028)) {
-               priv->hwmodel = hwmodel;
-               priv->hwvers  = version & 0xff00;
-       } else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel ||
-                  priv->hwvers != (version & 0xff00)) {
-               tuner_err("Read invalid device hardware information - tuner "
-                         "hung?\n");
-               goto fail;
-       }
-
-read_not_reliable:
-       memcpy(&priv->cur_fw, &new_fw, sizeof(priv->cur_fw));
-
-       /*
-        * By setting BASE in cur_fw.type only after successfully loading all
-        * firmwares, we can:
-        * 1. Identify that BASE firmware with type=0 has been loaded;
-        * 2. Tell whether BASE firmware was just changed the next time through.
-        */
-       priv->cur_fw.type |= BASE;
-       priv->state = XC2028_ACTIVE;
-
-       return 0;
-
-fail:
-       priv->state = XC2028_SLEEP;
-
-       memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
-       if (retry_count < 8) {
-               msleep(50);
-               retry_count++;
-               tuner_dbg("Retrying firmware load\n");
-               goto retry;
-       }
-
-       if (rc == -ENOENT)
-               rc = -EINVAL;
-       return rc;
-}
-
-static int xc2028_signal(struct dvb_frontend *fe, u16 *strength)
-{
-       struct xc2028_data *priv = fe->tuner_priv;
-       u16                 frq_lock, signal = 0;
-       int                 rc, i;
-
-       tuner_dbg("%s called\n", __func__);
-
-       rc = check_device_status(priv);
-       if (rc < 0)
-               return rc;
-
-       mutex_lock(&priv->lock);
-
-       /* Sync Lock Indicator */
-       for (i = 0; i < 3; i++) {
-               rc = xc2028_get_reg(priv, XREG_LOCK, &frq_lock);
-               if (rc < 0)
-                       goto ret;
-
-               if (frq_lock)
-                       break;
-               msleep(6);
-       }
-
-       /* Frequency didn't lock */
-       if (frq_lock == 2)
-               goto ret;
-
-       /* Get SNR of the video signal */
-       rc = xc2028_get_reg(priv, XREG_SNR, &signal);
-       if (rc < 0)
-               goto ret;
-
-       /* Signal level is 3 bits only */
-
-       signal = ((1 << 12) - 1) | ((signal & 0x07) << 12);
-
-ret:
-       mutex_unlock(&priv->lock);
-
-       *strength = signal;
-
-       tuner_dbg("signal strength is %d\n", signal);
-
-       return rc;
-}
-
-static int xc2028_get_afc(struct dvb_frontend *fe, s32 *afc)
-{
-       struct xc2028_data *priv = fe->tuner_priv;
-       int i, rc;
-       u16 frq_lock = 0;
-       s16 afc_reg = 0;
-
-       rc = check_device_status(priv);
-       if (rc < 0)
-               return rc;
-
-       mutex_lock(&priv->lock);
-
-       /* Sync Lock Indicator */
-       for (i = 0; i < 3; i++) {
-               rc = xc2028_get_reg(priv, XREG_LOCK, &frq_lock);
-               if (rc < 0)
-                       goto ret;
-
-               if (frq_lock)
-                       break;
-               msleep(6);
-       }
-
-       /* Frequency didn't lock */
-       if (frq_lock == 2)
-               goto ret;
-
-       /* Get AFC */
-       rc = xc2028_get_reg(priv, XREG_FREQ_ERROR, &afc_reg);
-       if (rc < 0)
-               goto ret;
-
-       *afc = afc_reg * 15625; /* Hz */
-
-       tuner_dbg("AFC is %d Hz\n", *afc);
-
-ret:
-       mutex_unlock(&priv->lock);
-
-       return rc;
-}
-
-#define DIV 15625
-
-static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
-                           enum v4l2_tuner_type new_type,
-                           unsigned int type,
-                           v4l2_std_id std,
-                           u16 int_freq)
-{
-       struct xc2028_data *priv = fe->tuner_priv;
-       int                rc = -EINVAL;
-       unsigned char      buf[4];
-       u32                div, offset = 0;
-
-       tuner_dbg("%s called\n", __func__);
-
-       mutex_lock(&priv->lock);
-
-       tuner_dbg("should set frequency %d kHz\n", freq / 1000);
-
-       if (check_firmware(fe, type, std, int_freq) < 0)
-               goto ret;
-
-       /* On some cases xc2028 can disable video output, if
-        * very weak signals are received. By sending a soft
-        * reset, this is re-enabled. So, it is better to always
-        * send a soft reset before changing channels, to be sure
-        * that xc2028 will be in a safe state.
-        * Maybe this might also be needed for DTV.
-        */
-       switch (new_type) {
-       case V4L2_TUNER_ANALOG_TV:
-               rc = send_seq(priv, {0x00, 0x00});
-
-               /* Analog mode requires offset = 0 */
-               break;
-       case V4L2_TUNER_RADIO:
-               /* Radio mode requires offset = 0 */
-               break;
-       case V4L2_TUNER_DIGITAL_TV:
-               /*
-                * Digital modes require an offset to adjust to the
-                * proper frequency. The offset depends on what
-                * firmware version is used.
-                */
-
-               /*
-                * Adjust to the center frequency. This is calculated by the
-                * formula: offset = 1.25MHz - BW/2
-                * For DTV 7/8, the firmware uses BW = 8000, so it needs a
-                * further adjustment to get the frequency center on VHF
-                */
-
-               /*
-                * The firmware DTV78 used to work fine in UHF band (8 MHz
-                * bandwidth) but not at all in VHF band (7 MHz bandwidth).
-                * The real problem was connected to the formula used to
-                * calculate the center frequency offset in VHF band.
-                * In fact, removing the 500KHz adjustment fixed the problem.
-                * This is coherent to what was implemented for the DTV7
-                * firmware.
-                * In the end, now the center frequency is the same for all 3
-                * firmwares (DTV7, DTV8, DTV78) and doesn't depend on channel
-                * bandwidth.
-                */
-
-               if (priv->cur_fw.type & DTV6)
-                       offset = 1750000;
-               else    /* DTV7 or DTV8 or DTV78 */
-                       offset = 2750000;
-
-               /*
-                * xc3028 additional "magic"
-                * Depending on the firmware version, it needs some adjustments
-                * to properly centralize the frequency. This seems to be
-                * needed to compensate the SCODE table adjustments made by
-                * newer firmwares
-                */
-
-               /*
-                * The proper adjustment would be to do it at s-code table.
-                * However, this didn't work, as reported by
-                * Robert Lowery <rglowery@exemail.com.au>
-                */
-
-#if 0
-               /*
-                * Still need tests for XC3028L (firmware 3.2 or upper)
-                * So, for now, let's just comment the per-firmware
-                * version of this change. Reports with xc3028l working
-                * with and without the lines bellow are welcome
-                */
-
-               if (priv->firm_version < 0x0302) {
-                       if (priv->cur_fw.type & DTV7)
-                               offset += 500000;
-               } else {
-                       if (priv->cur_fw.type & DTV7)
-                               offset -= 300000;
-                       else if (type != ATSC) /* DVB @6MHz, DTV 8 and DTV 7/8 */
-                               offset += 200000;
-               }
-#endif
-       }
-
-       div = (freq - offset + DIV / 2) / DIV;
-
-       /* CMD= Set frequency */
-       if (priv->firm_version < 0x0202)
-               rc = send_seq(priv, {0x00, XREG_RF_FREQ, 0x00, 0x00});
-       else
-               rc = send_seq(priv, {0x80, XREG_RF_FREQ, 0x00, 0x00});
-       if (rc < 0)
-               goto ret;
-
-       /* Return code shouldn't be checked.
-          The reset CLK is needed only with tm6000.
-          Driver should work fine even if this fails.
-        */
-       if (priv->ctrl.msleep)
-               msleep(priv->ctrl.msleep);
-       do_tuner_callback(fe, XC2028_RESET_CLK, 1);
-
-       msleep(10);
-
-       buf[0] = 0xff & (div >> 24);
-       buf[1] = 0xff & (div >> 16);
-       buf[2] = 0xff & (div >> 8);
-       buf[3] = 0xff & (div);
-
-       rc = i2c_send(priv, buf, sizeof(buf));
-       if (rc < 0)
-               goto ret;
-       msleep(100);
-
-       priv->frequency = freq;
-
-       tuner_dbg("divisor= %*ph (freq=%d.%03d)\n", 4, buf,
-              freq / 1000000, (freq % 1000000) / 1000);
-
-       rc = 0;
-
-ret:
-       mutex_unlock(&priv->lock);
-
-       return rc;
-}
-
-static int xc2028_set_analog_freq(struct dvb_frontend *fe,
-                             struct analog_parameters *p)
-{
-       struct xc2028_data *priv = fe->tuner_priv;
-       unsigned int       type=0;
-
-       tuner_dbg("%s called\n", __func__);
-
-       if (p->mode == V4L2_TUNER_RADIO) {
-               type |= FM;
-               if (priv->ctrl.input1)
-                       type |= INPUT1;
-               return generic_set_freq(fe, (625l * p->frequency) / 10,
-                               V4L2_TUNER_RADIO, type, 0, 0);
-       }
-
-       /* if std is not defined, choose one */
-       if (!p->std)
-               p->std = V4L2_STD_MN;
-
-       /* PAL/M, PAL/N, PAL/Nc and NTSC variants should use 6MHz firmware */
-       if (!(p->std & V4L2_STD_MN))
-               type |= F8MHZ;
-
-       /* Add audio hack to std mask */
-       p->std |= parse_audio_std_option();
-
-       return generic_set_freq(fe, 62500l * p->frequency,
-                               V4L2_TUNER_ANALOG_TV, type, p->std, 0);
-}
-
-static int xc2028_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u32 delsys = c->delivery_system;
-       u32 bw = c->bandwidth_hz;
-       struct xc2028_data *priv = fe->tuner_priv;
-       int rc;
-       unsigned int       type = 0;
-       u16                demod = 0;
-
-       tuner_dbg("%s called\n", __func__);
-
-       rc = check_device_status(priv);
-       if (rc < 0)
-               return rc;
-
-       switch (delsys) {
-       case SYS_DVBT:
-       case SYS_DVBT2:
-               /*
-                * The only countries with 6MHz seem to be Taiwan/Uruguay.
-                * Both seem to require QAM firmware for OFDM decoding
-                * Tested in Taiwan by Terry Wu <terrywu2009@gmail.com>
-                */
-               if (bw <= 6000000)
-                       type |= QAM;
-
-               switch (priv->ctrl.type) {
-               case XC2028_D2633:
-                       type |= D2633;
-                       break;
-               case XC2028_D2620:
-                       type |= D2620;
-                       break;
-               case XC2028_AUTO:
-               default:
-                       /* Zarlink seems to need D2633 */
-                       if (priv->ctrl.demod == XC3028_FE_ZARLINK456)
-                               type |= D2633;
-                       else
-                               type |= D2620;
-               }
-               break;
-       case SYS_ATSC:
-               /* The only ATSC firmware (at least on v2.7) is D2633 */
-               type |= ATSC | D2633;
-               break;
-       /* DVB-S and pure QAM (FE_QAM) are not supported */
-       default:
-               return -EINVAL;
-       }
-
-       if (bw <= 6000000) {
-               type |= DTV6;
-               priv->ctrl.vhfbw7 = 0;
-               priv->ctrl.uhfbw8 = 0;
-       } else if (bw <= 7000000) {
-               if (c->frequency < 470000000)
-                       priv->ctrl.vhfbw7 = 1;
-               else
-                       priv->ctrl.uhfbw8 = 0;
-               type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV7;
-               type |= F8MHZ;
-       } else {
-               if (c->frequency < 470000000)
-                       priv->ctrl.vhfbw7 = 0;
-               else
-                       priv->ctrl.uhfbw8 = 1;
-               type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV8;
-               type |= F8MHZ;
-       }
-
-       /* All S-code tables need a 200kHz shift */
-       if (priv->ctrl.demod) {
-               demod = priv->ctrl.demod;
-
-               /*
-                * Newer firmwares require a 200 kHz offset only for ATSC
-                */
-               if (type == ATSC || priv->firm_version < 0x0302)
-                       demod += 200;
-               /*
-                * The DTV7 S-code table needs a 700 kHz shift.
-                *
-                * DTV7 is only used in Australia.  Germany or Italy may also
-                * use this firmware after initialization, but a tune to a UHF
-                * channel should then cause DTV78 to be used.
-                *
-                * Unfortunately, on real-field tests, the s-code offset
-                * didn't work as expected, as reported by
-                * Robert Lowery <rglowery@exemail.com.au>
-                */
-       }
-
-       return generic_set_freq(fe, c->frequency,
-                               V4L2_TUNER_DIGITAL_TV, type, 0, demod);
-}
-
-static int xc2028_sleep(struct dvb_frontend *fe)
-{
-       struct xc2028_data *priv = fe->tuner_priv;
-       int rc;
-
-       rc = check_device_status(priv);
-       if (rc < 0)
-               return rc;
-
-       /* Avoid firmware reload on slow devices or if PM disabled */
-       if (no_poweroff || priv->ctrl.disable_power_mgmt)
-               return 0;
-
-       tuner_dbg("Putting xc2028/3028 into poweroff mode.\n");
-       if (debug > 1) {
-               tuner_dbg("Printing sleep stack trace:\n");
-               dump_stack();
-       }
-
-       mutex_lock(&priv->lock);
-
-       if (priv->firm_version < 0x0202)
-               rc = send_seq(priv, {0x00, XREG_POWER_DOWN, 0x00, 0x00});
-       else
-               rc = send_seq(priv, {0x80, XREG_POWER_DOWN, 0x00, 0x00});
-
-       priv->state = XC2028_SLEEP;
-
-       mutex_unlock(&priv->lock);
-
-       return rc;
-}
-
-static int xc2028_dvb_release(struct dvb_frontend *fe)
-{
-       struct xc2028_data *priv = fe->tuner_priv;
-
-       tuner_dbg("%s called\n", __func__);
-
-       mutex_lock(&xc2028_list_mutex);
-
-       /* only perform final cleanup if this is the last instance */
-       if (hybrid_tuner_report_instance_count(priv) == 1) {
-               free_firmware(priv);
-               kfree(priv->ctrl.fname);
-               priv->ctrl.fname = NULL;
-       }
-
-       if (priv)
-               hybrid_tuner_release_state(priv);
-
-       mutex_unlock(&xc2028_list_mutex);
-
-       fe->tuner_priv = NULL;
-
-       return 0;
-}
-
-static int xc2028_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct xc2028_data *priv = fe->tuner_priv;
-       int rc;
-
-       tuner_dbg("%s called\n", __func__);
-
-       rc = check_device_status(priv);
-       if (rc < 0)
-               return rc;
-
-       *frequency = priv->frequency;
-
-       return 0;
-}
-
-static void load_firmware_cb(const struct firmware *fw,
-                            void *context)
-{
-       struct dvb_frontend *fe = context;
-       struct xc2028_data *priv = fe->tuner_priv;
-       int rc;
-
-       tuner_dbg("request_firmware_nowait(): %s\n", fw ? "OK" : "error");
-       if (!fw) {
-               tuner_err("Could not load firmware %s.\n", priv->fname);
-               priv->state = XC2028_NODEV;
-               return;
-       }
-
-       rc = load_all_firmwares(fe, fw);
-
-       release_firmware(fw);
-
-       if (rc < 0)
-               return;
-       priv->state = XC2028_SLEEP;
-}
-
-static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
-{
-       struct xc2028_data *priv = fe->tuner_priv;
-       struct xc2028_ctrl *p    = priv_cfg;
-       int                 rc   = 0;
-
-       tuner_dbg("%s called\n", __func__);
-
-       mutex_lock(&priv->lock);
-
-       /*
-        * Copy the config data.
-        * For the firmware name, keep a local copy of the string,
-        * in order to avoid troubles during device release.
-        */
-       if (priv->ctrl.fname)
-               kfree(priv->ctrl.fname);
-       memcpy(&priv->ctrl, p, sizeof(priv->ctrl));
-       if (p->fname) {
-               priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL);
-               if (priv->ctrl.fname == NULL)
-                       rc = -ENOMEM;
-       }
-
-       /*
-        * If firmware name changed, frees firmware. As free_firmware will
-        * reset the status to NO_FIRMWARE, this forces a new request_firmware
-        */
-       if (!firmware_name[0] && p->fname &&
-           priv->fname && strcmp(p->fname, priv->fname))
-               free_firmware(priv);
-
-       if (priv->ctrl.max_len < 9)
-               priv->ctrl.max_len = 13;
-
-       if (priv->state == XC2028_NO_FIRMWARE) {
-               if (!firmware_name[0])
-                       priv->fname = priv->ctrl.fname;
-               else
-                       priv->fname = firmware_name;
-
-               rc = request_firmware_nowait(THIS_MODULE, 1,
-                                            priv->fname,
-                                            priv->i2c_props.adap->dev.parent,
-                                            GFP_KERNEL,
-                                            fe, load_firmware_cb);
-               if (rc < 0) {
-                       tuner_err("Failed to request firmware %s\n",
-                                 priv->fname);
-                       priv->state = XC2028_NODEV;
-               } else
-                       priv->state = XC2028_WAITING_FIRMWARE;
-       }
-       mutex_unlock(&priv->lock);
-
-       return rc;
-}
-
-static const struct dvb_tuner_ops xc2028_dvb_tuner_ops = {
-       .info = {
-                .name = "Xceive XC3028",
-                .frequency_min = 42000000,
-                .frequency_max = 864000000,
-                .frequency_step = 50000,
-                },
-
-       .set_config        = xc2028_set_config,
-       .set_analog_params = xc2028_set_analog_freq,
-       .release           = xc2028_dvb_release,
-       .get_frequency     = xc2028_get_frequency,
-       .get_rf_strength   = xc2028_signal,
-       .get_afc           = xc2028_get_afc,
-       .set_params        = xc2028_set_params,
-       .sleep             = xc2028_sleep,
-};
-
-struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
-                                  struct xc2028_config *cfg)
-{
-       struct xc2028_data *priv;
-       int instance;
-
-       if (debug)
-               printk(KERN_DEBUG "xc2028: Xcv2028/3028 init called!\n");
-
-       if (NULL == cfg)
-               return NULL;
-
-       if (!fe) {
-               printk(KERN_ERR "xc2028: No frontend!\n");
-               return NULL;
-       }
-
-       mutex_lock(&xc2028_list_mutex);
-
-       instance = hybrid_tuner_request_state(struct xc2028_data, priv,
-                                             hybrid_tuner_instance_list,
-                                             cfg->i2c_adap, cfg->i2c_addr,
-                                             "xc2028");
-       switch (instance) {
-       case 0:
-               /* memory allocation failure */
-               goto fail;
-               break;
-       case 1:
-               /* new tuner instance */
-               priv->ctrl.max_len = 13;
-
-               mutex_init(&priv->lock);
-
-               fe->tuner_priv = priv;
-               break;
-       case 2:
-               /* existing tuner instance */
-               fe->tuner_priv = priv;
-               break;
-       }
-
-       memcpy(&fe->ops.tuner_ops, &xc2028_dvb_tuner_ops,
-              sizeof(xc2028_dvb_tuner_ops));
-
-       tuner_info("type set to %s\n", "XCeive xc2028/xc3028 tuner");
-
-       if (cfg->ctrl)
-               xc2028_set_config(fe, cfg->ctrl);
-
-       mutex_unlock(&xc2028_list_mutex);
-
-       return fe;
-fail:
-       mutex_unlock(&xc2028_list_mutex);
-
-       xc2028_dvb_release(fe);
-       return NULL;
-}
-
-EXPORT_SYMBOL(xc2028_attach);
-
-MODULE_DESCRIPTION("Xceive xc2028/xc3028 tuner driver");
-MODULE_AUTHOR("Michel Ludwig <michel.ludwig@gmail.com>");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(XC2028_DEFAULT_FIRMWARE);
-MODULE_FIRMWARE(XC3028L_DEFAULT_FIRMWARE);
diff --git a/drivers/media/common/tuners/tuner-xc2028.h b/drivers/media/common/tuners/tuner-xc2028.h
deleted file mode 100644 (file)
index 9ebfb2d..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* tuner-xc2028
- *
- * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNU General Public License v2
- */
-
-#ifndef __TUNER_XC2028_H__
-#define __TUNER_XC2028_H__
-
-#include "dvb_frontend.h"
-
-#define XC2028_DEFAULT_FIRMWARE "xc3028-v27.fw"
-#define XC3028L_DEFAULT_FIRMWARE "xc3028L-v36.fw"
-
-/*      Dmoduler               IF (kHz) */
-#define        XC3028_FE_DEFAULT       0               /* Don't load SCODE */
-#define XC3028_FE_LG60         6000
-#define        XC3028_FE_ATI638        6380
-#define        XC3028_FE_OREN538       5380
-#define        XC3028_FE_OREN36        3600
-#define        XC3028_FE_TOYOTA388     3880
-#define        XC3028_FE_TOYOTA794     7940
-#define        XC3028_FE_DIBCOM52      5200
-#define        XC3028_FE_ZARLINK456    4560
-#define        XC3028_FE_CHINA         5200
-
-enum firmware_type {
-       XC2028_AUTO = 0,        /* By default, auto-detects */
-       XC2028_D2633,
-       XC2028_D2620,
-};
-
-struct xc2028_ctrl {
-       char                    *fname;
-       int                     max_len;
-       int                     msleep;
-       unsigned int            scode_table;
-       unsigned int            mts   :1;
-       unsigned int            input1:1;
-       unsigned int            vhfbw7:1;
-       unsigned int            uhfbw8:1;
-       unsigned int            disable_power_mgmt:1;
-       unsigned int            read_not_reliable:1;
-       unsigned int            demod;
-       enum firmware_type      type:2;
-};
-
-struct xc2028_config {
-       struct i2c_adapter *i2c_adap;
-       u8                 i2c_addr;
-       struct xc2028_ctrl *ctrl;
-};
-
-/* xc2028 commands for callback */
-#define XC2028_TUNER_RESET     0
-#define XC2028_RESET_CLK       1
-#define XC2028_I2C_FLUSH       2
-
-#if defined(CONFIG_MEDIA_TUNER_XC2028) || (defined(CONFIG_MEDIA_TUNER_XC2028_MODULE) && defined(MODULE))
-extern struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
-                                         struct xc2028_config *cfg);
-#else
-static inline struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
-                                                struct xc2028_config *cfg)
-{
-       printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
-              __func__);
-       return NULL;
-}
-#endif
-
-#endif /* __TUNER_XC2028_H__ */
diff --git a/drivers/media/common/tuners/xc4000.c b/drivers/media/common/tuners/xc4000.c
deleted file mode 100644 (file)
index 4937712..0000000
+++ /dev/null
@@ -1,1757 +0,0 @@
-/*
- *  Driver for Xceive XC4000 "QAM/8VSB single chip tuner"
- *
- *  Copyright (c) 2007 Xceive Corporation
- *  Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
- *  Copyright (c) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
- *  Copyright (c) 2009 Davide Ferri <d.ferri@zero11.it>
- *  Copyright (c) 2010 Istvan Varga <istvan_v@mailbox.hu>
- *
- *  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.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/videodev2.h>
-#include <linux/delay.h>
-#include <linux/dvb/frontend.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-#include <asm/unaligned.h>
-
-#include "dvb_frontend.h"
-
-#include "xc4000.h"
-#include "tuner-i2c.h"
-#include "tuner-xc2028-types.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debugging level (0 to 2, default: 0 (off)).");
-
-static int no_poweroff;
-module_param(no_poweroff, int, 0644);
-MODULE_PARM_DESC(no_poweroff, "Power management (1: disabled, 2: enabled, "
-       "0 (default): use device-specific default mode).");
-
-static int audio_std;
-module_param(audio_std, int, 0644);
-MODULE_PARM_DESC(audio_std, "Audio standard. XC4000 audio decoder explicitly "
-       "needs to know what audio standard is needed for some video standards "
-       "with audio A2 or NICAM. The valid settings are a sum of:\n"
-       " 1: use NICAM/B or A2/B instead of NICAM/A or A2/A\n"
-       " 2: use A2 instead of NICAM or BTSC\n"
-       " 4: use SECAM/K3 instead of K1\n"
-       " 8: use PAL-D/K audio for SECAM-D/K\n"
-       "16: use FM radio input 1 instead of input 2\n"
-       "32: use mono audio (the lower three bits are ignored)");
-
-static char firmware_name[30];
-module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0);
-MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the "
-       "default firmware name.");
-
-static DEFINE_MUTEX(xc4000_list_mutex);
-static LIST_HEAD(hybrid_tuner_instance_list);
-
-#define dprintk(level, fmt, arg...) if (debug >= level) \
-       printk(KERN_INFO "%s: " fmt, "xc4000", ## arg)
-
-/* struct for storing firmware table */
-struct firmware_description {
-       unsigned int  type;
-       v4l2_std_id   id;
-       __u16         int_freq;
-       unsigned char *ptr;
-       unsigned int  size;
-};
-
-struct firmware_properties {
-       unsigned int    type;
-       v4l2_std_id     id;
-       v4l2_std_id     std_req;
-       __u16           int_freq;
-       unsigned int    scode_table;
-       int             scode_nr;
-};
-
-struct xc4000_priv {
-       struct tuner_i2c_props i2c_props;
-       struct list_head hybrid_tuner_instance_list;
-       struct firmware_description *firm;
-       int     firm_size;
-       u32     if_khz;
-       u32     freq_hz;
-       u32     bandwidth;
-       u8      video_standard;
-       u8      rf_mode;
-       u8      default_pm;
-       u8      dvb_amplitude;
-       u8      set_smoothedcvbs;
-       u8      ignore_i2c_write_errors;
-       __u16   firm_version;
-       struct firmware_properties cur_fw;
-       __u16   hwmodel;
-       __u16   hwvers;
-       struct mutex    lock;
-};
-
-#define XC4000_AUDIO_STD_B              1
-#define XC4000_AUDIO_STD_A2             2
-#define XC4000_AUDIO_STD_K3             4
-#define XC4000_AUDIO_STD_L              8
-#define XC4000_AUDIO_STD_INPUT1                16
-#define XC4000_AUDIO_STD_MONO          32
-
-#define XC4000_DEFAULT_FIRMWARE "dvb-fe-xc4000-1.4.fw"
-
-/* Misc Defines */
-#define MAX_TV_STANDARD                        24
-#define XC_MAX_I2C_WRITE_LENGTH                64
-#define XC_POWERED_DOWN                        0x80000000U
-
-/* Signal Types */
-#define XC_RF_MODE_AIR                 0
-#define XC_RF_MODE_CABLE               1
-
-/* Product id */
-#define XC_PRODUCT_ID_FW_NOT_LOADED    0x2000
-#define XC_PRODUCT_ID_XC4000           0x0FA0
-#define XC_PRODUCT_ID_XC4100           0x1004
-
-/* Registers (Write-only) */
-#define XREG_INIT         0x00
-#define XREG_VIDEO_MODE   0x01
-#define XREG_AUDIO_MODE   0x02
-#define XREG_RF_FREQ      0x03
-#define XREG_D_CODE       0x04
-#define XREG_DIRECTSITTING_MODE 0x05
-#define XREG_SEEK_MODE    0x06
-#define XREG_POWER_DOWN   0x08
-#define XREG_SIGNALSOURCE 0x0A
-#define XREG_SMOOTHEDCVBS 0x0E
-#define XREG_AMPLITUDE    0x10
-
-/* Registers (Read-only) */
-#define XREG_ADC_ENV      0x00
-#define XREG_QUALITY      0x01
-#define XREG_FRAME_LINES  0x02
-#define XREG_HSYNC_FREQ   0x03
-#define XREG_LOCK         0x04
-#define XREG_FREQ_ERROR   0x05
-#define XREG_SNR          0x06
-#define XREG_VERSION      0x07
-#define XREG_PRODUCT_ID   0x08
-#define XREG_SIGNAL_LEVEL 0x0A
-#define XREG_NOISE_LEVEL  0x0B
-
-/*
-   Basic firmware description. This will remain with
-   the driver for documentation purposes.
-
-   This represents an I2C firmware file encoded as a
-   string of unsigned char. Format is as follows:
-
-   char[0  ]=len0_MSB  -> len = len_MSB * 256 + len_LSB
-   char[1  ]=len0_LSB  -> length of first write transaction
-   char[2  ]=data0 -> first byte to be sent
-   char[3  ]=data1
-   char[4  ]=data2
-   char[   ]=...
-   char[M  ]=dataN  -> last byte to be sent
-   char[M+1]=len1_MSB  -> len = len_MSB * 256 + len_LSB
-   char[M+2]=len1_LSB  -> length of second write transaction
-   char[M+3]=data0
-   char[M+4]=data1
-   ...
-   etc.
-
-   The [len] value should be interpreted as follows:
-
-   len= len_MSB _ len_LSB
-   len=1111_1111_1111_1111   : End of I2C_SEQUENCE
-   len=0000_0000_0000_0000   : Reset command: Do hardware reset
-   len=0NNN_NNNN_NNNN_NNNN   : Normal transaction: number of bytes = {1:32767)
-   len=1WWW_WWWW_WWWW_WWWW   : Wait command: wait for {1:32767} ms
-
-   For the RESET and WAIT commands, the two following bytes will contain
-   immediately the length of the following transaction.
-*/
-
-struct XC_TV_STANDARD {
-       const char  *Name;
-       u16         audio_mode;
-       u16         video_mode;
-       u16         int_freq;
-};
-
-/* Tuner standards */
-#define XC4000_MN_NTSC_PAL_BTSC                0
-#define XC4000_MN_NTSC_PAL_A2          1
-#define XC4000_MN_NTSC_PAL_EIAJ                2
-#define XC4000_MN_NTSC_PAL_Mono                3
-#define XC4000_BG_PAL_A2               4
-#define XC4000_BG_PAL_NICAM            5
-#define XC4000_BG_PAL_MONO             6
-#define XC4000_I_PAL_NICAM             7
-#define XC4000_I_PAL_NICAM_MONO                8
-#define XC4000_DK_PAL_A2               9
-#define XC4000_DK_PAL_NICAM            10
-#define XC4000_DK_PAL_MONO             11
-#define XC4000_DK_SECAM_A2DK1          12
-#define XC4000_DK_SECAM_A2LDK3         13
-#define XC4000_DK_SECAM_A2MONO         14
-#define XC4000_DK_SECAM_NICAM          15
-#define XC4000_L_SECAM_NICAM           16
-#define XC4000_LC_SECAM_NICAM          17
-#define XC4000_DTV6                    18
-#define XC4000_DTV8                    19
-#define XC4000_DTV7_8                  20
-#define XC4000_DTV7                    21
-#define XC4000_FM_Radio_INPUT2         22
-#define XC4000_FM_Radio_INPUT1         23
-
-static struct XC_TV_STANDARD xc4000_standard[MAX_TV_STANDARD] = {
-       {"M/N-NTSC/PAL-BTSC",   0x0000, 0x80A0, 4500},
-       {"M/N-NTSC/PAL-A2",     0x0000, 0x80A0, 4600},
-       {"M/N-NTSC/PAL-EIAJ",   0x0040, 0x80A0, 4500},
-       {"M/N-NTSC/PAL-Mono",   0x0078, 0x80A0, 4500},
-       {"B/G-PAL-A2",          0x0000, 0x8159, 5640},
-       {"B/G-PAL-NICAM",       0x0004, 0x8159, 5740},
-       {"B/G-PAL-MONO",        0x0078, 0x8159, 5500},
-       {"I-PAL-NICAM",         0x0080, 0x8049, 6240},
-       {"I-PAL-NICAM-MONO",    0x0078, 0x8049, 6000},
-       {"D/K-PAL-A2",          0x0000, 0x8049, 6380},
-       {"D/K-PAL-NICAM",       0x0080, 0x8049, 6200},
-       {"D/K-PAL-MONO",        0x0078, 0x8049, 6500},
-       {"D/K-SECAM-A2 DK1",    0x0000, 0x8049, 6340},
-       {"D/K-SECAM-A2 L/DK3",  0x0000, 0x8049, 6000},
-       {"D/K-SECAM-A2 MONO",   0x0078, 0x8049, 6500},
-       {"D/K-SECAM-NICAM",     0x0080, 0x8049, 6200},
-       {"L-SECAM-NICAM",       0x8080, 0x0009, 6200},
-       {"L'-SECAM-NICAM",      0x8080, 0x4009, 6200},
-       {"DTV6",                0x00C0, 0x8002,    0},
-       {"DTV8",                0x00C0, 0x800B,    0},
-       {"DTV7/8",              0x00C0, 0x801B,    0},
-       {"DTV7",                0x00C0, 0x8007,    0},
-       {"FM Radio-INPUT2",     0x0008, 0x9800, 10700},
-       {"FM Radio-INPUT1",     0x0008, 0x9000, 10700}
-};
-
-static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val);
-static int xc4000_tuner_reset(struct dvb_frontend *fe);
-static void xc_debug_dump(struct xc4000_priv *priv);
-
-static int xc_send_i2c_data(struct xc4000_priv *priv, u8 *buf, int len)
-{
-       struct i2c_msg msg = { .addr = priv->i2c_props.addr,
-                              .flags = 0, .buf = buf, .len = len };
-       if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
-               if (priv->ignore_i2c_write_errors == 0) {
-                       printk(KERN_ERR "xc4000: I2C write failed (len=%i)\n",
-                              len);
-                       if (len == 4) {
-                               printk(KERN_ERR "bytes %*ph\n", 4, buf);
-                       }
-                       return -EREMOTEIO;
-               }
-       }
-       return 0;
-}
-
-static int xc4000_tuner_reset(struct dvb_frontend *fe)
-{
-       struct xc4000_priv *priv = fe->tuner_priv;
-       int ret;
-
-       dprintk(1, "%s()\n", __func__);
-
-       if (fe->callback) {
-               ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
-                                          fe->dvb->priv :
-                                          priv->i2c_props.adap->algo_data,
-                                          DVB_FRONTEND_COMPONENT_TUNER,
-                                          XC4000_TUNER_RESET, 0);
-               if (ret) {
-                       printk(KERN_ERR "xc4000: reset failed\n");
-                       return -EREMOTEIO;
-               }
-       } else {
-               printk(KERN_ERR "xc4000: no tuner reset callback function, "
-                               "fatal\n");
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static int xc_write_reg(struct xc4000_priv *priv, u16 regAddr, u16 i2cData)
-{
-       u8 buf[4];
-       int result;
-
-       buf[0] = (regAddr >> 8) & 0xFF;
-       buf[1] = regAddr & 0xFF;
-       buf[2] = (i2cData >> 8) & 0xFF;
-       buf[3] = i2cData & 0xFF;
-       result = xc_send_i2c_data(priv, buf, 4);
-
-       return result;
-}
-
-static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
-{
-       struct xc4000_priv *priv = fe->tuner_priv;
-
-       int i, nbytes_to_send, result;
-       unsigned int len, pos, index;
-       u8 buf[XC_MAX_I2C_WRITE_LENGTH];
-
-       index = 0;
-       while ((i2c_sequence[index] != 0xFF) ||
-               (i2c_sequence[index + 1] != 0xFF)) {
-               len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
-               if (len == 0x0000) {
-                       /* RESET command */
-                       /* NOTE: this is ignored, as the reset callback was */
-                       /* already called by check_firmware() */
-                       index += 2;
-               } else if (len & 0x8000) {
-                       /* WAIT command */
-                       msleep(len & 0x7FFF);
-                       index += 2;
-               } else {
-                       /* Send i2c data whilst ensuring individual transactions
-                        * do not exceed XC_MAX_I2C_WRITE_LENGTH bytes.
-                        */
-                       index += 2;
-                       buf[0] = i2c_sequence[index];
-                       buf[1] = i2c_sequence[index + 1];
-                       pos = 2;
-                       while (pos < len) {
-                               if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
-                                       nbytes_to_send =
-                                               XC_MAX_I2C_WRITE_LENGTH;
-                               else
-                                       nbytes_to_send = (len - pos + 2);
-                               for (i = 2; i < nbytes_to_send; i++) {
-                                       buf[i] = i2c_sequence[index + pos +
-                                               i - 2];
-                               }
-                               result = xc_send_i2c_data(priv, buf,
-                                       nbytes_to_send);
-
-                               if (result != 0)
-                                       return result;
-
-                               pos += nbytes_to_send - 2;
-                       }
-                       index += len;
-               }
-       }
-       return 0;
-}
-
-static int xc_set_tv_standard(struct xc4000_priv *priv,
-       u16 video_mode, u16 audio_mode)
-{
-       int ret;
-       dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, video_mode, audio_mode);
-       dprintk(1, "%s() Standard = %s\n",
-               __func__,
-               xc4000_standard[priv->video_standard].Name);
-
-       /* Don't complain when the request fails because of i2c stretching */
-       priv->ignore_i2c_write_errors = 1;
-
-       ret = xc_write_reg(priv, XREG_VIDEO_MODE, video_mode);
-       if (ret == 0)
-               ret = xc_write_reg(priv, XREG_AUDIO_MODE, audio_mode);
-
-       priv->ignore_i2c_write_errors = 0;
-
-       return ret;
-}
-
-static int xc_set_signal_source(struct xc4000_priv *priv, u16 rf_mode)
-{
-       dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
-               rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
-
-       if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
-               rf_mode = XC_RF_MODE_CABLE;
-               printk(KERN_ERR
-                       "%s(), Invalid mode, defaulting to CABLE",
-                       __func__);
-       }
-       return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
-}
-
-static const struct dvb_tuner_ops xc4000_tuner_ops;
-
-static int xc_set_rf_frequency(struct xc4000_priv *priv, u32 freq_hz)
-{
-       u16 freq_code;
-
-       dprintk(1, "%s(%u)\n", __func__, freq_hz);
-
-       if ((freq_hz > xc4000_tuner_ops.info.frequency_max) ||
-           (freq_hz < xc4000_tuner_ops.info.frequency_min))
-               return -EINVAL;
-
-       freq_code = (u16)(freq_hz / 15625);
-
-       /* WAS: Starting in firmware version 1.1.44, Xceive recommends using the
-          FINERFREQ for all normal tuning (the doc indicates reg 0x03 should
-          only be used for fast scanning for channel lock) */
-       /* WAS: XREG_FINERFREQ */
-       return xc_write_reg(priv, XREG_RF_FREQ, freq_code);
-}
-
-static int xc_get_adc_envelope(struct xc4000_priv *priv, u16 *adc_envelope)
-{
-       return xc4000_readreg(priv, XREG_ADC_ENV, adc_envelope);
-}
-
-static int xc_get_frequency_error(struct xc4000_priv *priv, u32 *freq_error_hz)
-{
-       int result;
-       u16 regData;
-       u32 tmp;
-
-       result = xc4000_readreg(priv, XREG_FREQ_ERROR, &regData);
-       if (result != 0)
-               return result;
-
-       tmp = (u32)regData & 0xFFFFU;
-       tmp = (tmp < 0x8000U ? tmp : 0x10000U - tmp);
-       (*freq_error_hz) = tmp * 15625;
-       return result;
-}
-
-static int xc_get_lock_status(struct xc4000_priv *priv, u16 *lock_status)
-{
-       return xc4000_readreg(priv, XREG_LOCK, lock_status);
-}
-
-static int xc_get_version(struct xc4000_priv *priv,
-       u8 *hw_majorversion, u8 *hw_minorversion,
-       u8 *fw_majorversion, u8 *fw_minorversion)
-{
-       u16 data;
-       int result;
-
-       result = xc4000_readreg(priv, XREG_VERSION, &data);
-       if (result != 0)
-               return result;
-
-       (*hw_majorversion) = (data >> 12) & 0x0F;
-       (*hw_minorversion) = (data >>  8) & 0x0F;
-       (*fw_majorversion) = (data >>  4) & 0x0F;
-       (*fw_minorversion) = data & 0x0F;
-
-       return 0;
-}
-
-static int xc_get_hsync_freq(struct xc4000_priv *priv, u32 *hsync_freq_hz)
-{
-       u16 regData;
-       int result;
-
-       result = xc4000_readreg(priv, XREG_HSYNC_FREQ, &regData);
-       if (result != 0)
-               return result;
-
-       (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
-       return result;
-}
-
-static int xc_get_frame_lines(struct xc4000_priv *priv, u16 *frame_lines)
-{
-       return xc4000_readreg(priv, XREG_FRAME_LINES, frame_lines);
-}
-
-static int xc_get_quality(struct xc4000_priv *priv, u16 *quality)
-{
-       return xc4000_readreg(priv, XREG_QUALITY, quality);
-}
-
-static int xc_get_signal_level(struct xc4000_priv *priv, u16 *signal)
-{
-       return xc4000_readreg(priv, XREG_SIGNAL_LEVEL, signal);
-}
-
-static int xc_get_noise_level(struct xc4000_priv *priv, u16 *noise)
-{
-       return xc4000_readreg(priv, XREG_NOISE_LEVEL, noise);
-}
-
-static u16 xc_wait_for_lock(struct xc4000_priv *priv)
-{
-       u16     lock_state = 0;
-       int     watchdog_count = 40;
-
-       while ((lock_state == 0) && (watchdog_count > 0)) {
-               xc_get_lock_status(priv, &lock_state);
-               if (lock_state != 1) {
-                       msleep(5);
-                       watchdog_count--;
-               }
-       }
-       return lock_state;
-}
-
-static int xc_tune_channel(struct xc4000_priv *priv, u32 freq_hz)
-{
-       int     found = 1;
-       int     result;
-
-       dprintk(1, "%s(%u)\n", __func__, freq_hz);
-
-       /* Don't complain when the request fails because of i2c stretching */
-       priv->ignore_i2c_write_errors = 1;
-       result = xc_set_rf_frequency(priv, freq_hz);
-       priv->ignore_i2c_write_errors = 0;
-
-       if (result != 0)
-               return 0;
-
-       /* wait for lock only in analog TV mode */
-       if ((priv->cur_fw.type & (FM | DTV6 | DTV7 | DTV78 | DTV8)) == 0) {
-               if (xc_wait_for_lock(priv) != 1)
-                       found = 0;
-       }
-
-       /* Wait for stats to stabilize.
-        * Frame Lines needs two frame times after initial lock
-        * before it is valid.
-        */
-       msleep(debug ? 100 : 10);
-
-       if (debug)
-               xc_debug_dump(priv);
-
-       return found;
-}
-
-static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val)
-{
-       u8 buf[2] = { reg >> 8, reg & 0xff };
-       u8 bval[2] = { 0, 0 };
-       struct i2c_msg msg[2] = {
-               { .addr = priv->i2c_props.addr,
-                       .flags = 0, .buf = &buf[0], .len = 2 },
-               { .addr = priv->i2c_props.addr,
-                       .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
-       };
-
-       if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
-               printk(KERN_ERR "xc4000: I2C read failed\n");
-               return -EREMOTEIO;
-       }
-
-       *val = (bval[0] << 8) | bval[1];
-       return 0;
-}
-
-#define dump_firm_type(t)      dump_firm_type_and_int_freq(t, 0)
-static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
-{
-        if (type & BASE)
-               printk(KERN_CONT "BASE ");
-        if (type & INIT1)
-               printk(KERN_CONT "INIT1 ");
-        if (type & F8MHZ)
-               printk(KERN_CONT "F8MHZ ");
-        if (type & MTS)
-               printk(KERN_CONT "MTS ");
-        if (type & D2620)
-               printk(KERN_CONT "D2620 ");
-        if (type & D2633)
-               printk(KERN_CONT "D2633 ");
-        if (type & DTV6)
-               printk(KERN_CONT "DTV6 ");
-        if (type & QAM)
-               printk(KERN_CONT "QAM ");
-        if (type & DTV7)
-               printk(KERN_CONT "DTV7 ");
-        if (type & DTV78)
-               printk(KERN_CONT "DTV78 ");
-        if (type & DTV8)
-               printk(KERN_CONT "DTV8 ");
-        if (type & FM)
-               printk(KERN_CONT "FM ");
-        if (type & INPUT1)
-               printk(KERN_CONT "INPUT1 ");
-        if (type & LCD)
-               printk(KERN_CONT "LCD ");
-        if (type & NOGD)
-               printk(KERN_CONT "NOGD ");
-        if (type & MONO)
-               printk(KERN_CONT "MONO ");
-        if (type & ATSC)
-               printk(KERN_CONT "ATSC ");
-        if (type & IF)
-               printk(KERN_CONT "IF ");
-        if (type & LG60)
-               printk(KERN_CONT "LG60 ");
-        if (type & ATI638)
-               printk(KERN_CONT "ATI638 ");
-        if (type & OREN538)
-               printk(KERN_CONT "OREN538 ");
-        if (type & OREN36)
-               printk(KERN_CONT "OREN36 ");
-        if (type & TOYOTA388)
-               printk(KERN_CONT "TOYOTA388 ");
-        if (type & TOYOTA794)
-               printk(KERN_CONT "TOYOTA794 ");
-        if (type & DIBCOM52)
-               printk(KERN_CONT "DIBCOM52 ");
-        if (type & ZARLINK456)
-               printk(KERN_CONT "ZARLINK456 ");
-        if (type & CHINA)
-               printk(KERN_CONT "CHINA ");
-        if (type & F6MHZ)
-               printk(KERN_CONT "F6MHZ ");
-        if (type & INPUT2)
-               printk(KERN_CONT "INPUT2 ");
-        if (type & SCODE)
-               printk(KERN_CONT "SCODE ");
-        if (type & HAS_IF)
-               printk(KERN_CONT "HAS_IF_%d ", int_freq);
-}
-
-static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
-                        v4l2_std_id *id)
-{
-       struct xc4000_priv *priv = fe->tuner_priv;
-       int             i, best_i = -1;
-       unsigned int    best_nr_diffs = 255U;
-
-       if (!priv->firm) {
-               printk(KERN_ERR "Error! firmware not loaded\n");
-               return -EINVAL;
-       }
-
-       if (((type & ~SCODE) == 0) && (*id == 0))
-               *id = V4L2_STD_PAL;
-
-       /* Seek for generic video standard match */
-       for (i = 0; i < priv->firm_size; i++) {
-               v4l2_std_id     id_diff_mask =
-                       (priv->firm[i].id ^ (*id)) & (*id);
-               unsigned int    type_diff_mask =
-                       (priv->firm[i].type ^ type)
-                       & (BASE_TYPES | DTV_TYPES | LCD | NOGD | MONO | SCODE);
-               unsigned int    nr_diffs;
-
-               if (type_diff_mask
-                   & (BASE | INIT1 | FM | DTV6 | DTV7 | DTV78 | DTV8 | SCODE))
-                       continue;
-
-               nr_diffs = hweight64(id_diff_mask) + hweight32(type_diff_mask);
-               if (!nr_diffs)  /* Supports all the requested standards */
-                       goto found;
-
-               if (nr_diffs < best_nr_diffs) {
-                       best_nr_diffs = nr_diffs;
-                       best_i = i;
-               }
-       }
-
-       /* FIXME: Would make sense to seek for type "hint" match ? */
-       if (best_i < 0) {
-               i = -ENOENT;
-               goto ret;
-       }
-
-       if (best_nr_diffs > 0U) {
-               printk(KERN_WARNING
-                      "Selecting best matching firmware (%u bits differ) for "
-                      "type=(%x), id %016llx:\n",
-                      best_nr_diffs, type, (unsigned long long)*id);
-               i = best_i;
-       }
-
-found:
-       *id = priv->firm[i].id;
-
-ret:
-       if (debug) {
-               printk(KERN_DEBUG "%s firmware for type=",
-                      (i < 0) ? "Can't find" : "Found");
-               dump_firm_type(type);
-               printk(KERN_DEBUG "(%x), id %016llx.\n", type, (unsigned long long)*id);
-       }
-       return i;
-}
-
-static int load_firmware(struct dvb_frontend *fe, unsigned int type,
-                        v4l2_std_id *id)
-{
-       struct xc4000_priv *priv = fe->tuner_priv;
-       int                pos, rc;
-       unsigned char      *p;
-
-       pos = seek_firmware(fe, type, id);
-       if (pos < 0)
-               return pos;
-
-       p = priv->firm[pos].ptr;
-
-       /* Don't complain when the request fails because of i2c stretching */
-       priv->ignore_i2c_write_errors = 1;
-
-       rc = xc_load_i2c_sequence(fe, p);
-
-       priv->ignore_i2c_write_errors = 0;
-
-       return rc;
-}
-
-static int xc4000_fwupload(struct dvb_frontend *fe)
-{
-       struct xc4000_priv *priv = fe->tuner_priv;
-       const struct firmware *fw   = NULL;
-       const unsigned char   *p, *endp;
-       int                   rc = 0;
-       int                   n, n_array;
-       char                  name[33];
-       const char            *fname;
-
-       if (firmware_name[0] != '\0')
-               fname = firmware_name;
-       else
-               fname = XC4000_DEFAULT_FIRMWARE;
-
-       dprintk(1, "Reading firmware %s\n", fname);
-       rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent);
-       if (rc < 0) {
-               if (rc == -ENOENT)
-                       printk(KERN_ERR "Error: firmware %s not found.\n", fname);
-               else
-                       printk(KERN_ERR "Error %d while requesting firmware %s\n",
-                              rc, fname);
-
-               return rc;
-       }
-       p = fw->data;
-       endp = p + fw->size;
-
-       if (fw->size < sizeof(name) - 1 + 2 + 2) {
-               printk(KERN_ERR "Error: firmware file %s has invalid size!\n",
-                      fname);
-               goto corrupt;
-       }
-
-       memcpy(name, p, sizeof(name) - 1);
-       name[sizeof(name) - 1] = '\0';
-       p += sizeof(name) - 1;
-
-       priv->firm_version = get_unaligned_le16(p);
-       p += 2;
-
-       n_array = get_unaligned_le16(p);
-       p += 2;
-
-       dprintk(1, "Loading %d firmware images from %s, type: %s, ver %d.%d\n",
-               n_array, fname, name,
-               priv->firm_version >> 8, priv->firm_version & 0xff);
-
-       priv->firm = kcalloc(n_array, sizeof(*priv->firm), GFP_KERNEL);
-       if (priv->firm == NULL) {
-               printk(KERN_ERR "Not enough memory to load firmware file.\n");
-               rc = -ENOMEM;
-               goto done;
-       }
-       priv->firm_size = n_array;
-
-       n = -1;
-       while (p < endp) {
-               __u32 type, size;
-               v4l2_std_id id;
-               __u16 int_freq = 0;
-
-               n++;
-               if (n >= n_array) {
-                       printk(KERN_ERR "More firmware images in file than "
-                              "were expected!\n");
-                       goto corrupt;
-               }
-
-               /* Checks if there's enough bytes to read */
-               if (endp - p < sizeof(type) + sizeof(id) + sizeof(size))
-                       goto header;
-
-               type = get_unaligned_le32(p);
-               p += sizeof(type);
-
-               id = get_unaligned_le64(p);
-               p += sizeof(id);
-
-               if (type & HAS_IF) {
-                       int_freq = get_unaligned_le16(p);
-                       p += sizeof(int_freq);
-                       if (endp - p < sizeof(size))
-                               goto header;
-               }
-
-               size = get_unaligned_le32(p);
-               p += sizeof(size);
-
-               if (!size || size > endp - p) {
-                       printk(KERN_ERR "Firmware type (%x), id %llx is corrupted (size=%d, expected %d)\n",
-                              type, (unsigned long long)id,
-                              (unsigned)(endp - p), size);
-                       goto corrupt;
-               }
-
-               priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
-               if (priv->firm[n].ptr == NULL) {
-                       printk(KERN_ERR "Not enough memory to load firmware file.\n");
-                       rc = -ENOMEM;
-                       goto done;
-               }
-
-               if (debug) {
-                       printk(KERN_DEBUG "Reading firmware type ");
-                       dump_firm_type_and_int_freq(type, int_freq);
-                       printk(KERN_DEBUG "(%x), id %llx, size=%d.\n",
-                              type, (unsigned long long)id, size);
-               }
-
-               memcpy(priv->firm[n].ptr, p, size);
-               priv->firm[n].type = type;
-               priv->firm[n].id   = id;
-               priv->firm[n].size = size;
-               priv->firm[n].int_freq = int_freq;
-
-               p += size;
-       }
-
-       if (n + 1 != priv->firm_size) {
-               printk(KERN_ERR "Firmware file is incomplete!\n");
-               goto corrupt;
-       }
-
-       goto done;
-
-header:
-       printk(KERN_ERR "Firmware header is incomplete!\n");
-corrupt:
-       rc = -EINVAL;
-       printk(KERN_ERR "Error: firmware file is corrupted!\n");
-
-done:
-       release_firmware(fw);
-       if (rc == 0)
-               dprintk(1, "Firmware files loaded.\n");
-
-       return rc;
-}
-
-static int load_scode(struct dvb_frontend *fe, unsigned int type,
-                        v4l2_std_id *id, __u16 int_freq, int scode)
-{
-       struct xc4000_priv *priv = fe->tuner_priv;
-       int             pos, rc;
-       unsigned char   *p;
-       u8              scode_buf[13];
-       u8              indirect_mode[5];
-
-       dprintk(1, "%s called int_freq=%d\n", __func__, int_freq);
-
-       if (!int_freq) {
-               pos = seek_firmware(fe, type, id);
-               if (pos < 0)
-                       return pos;
-       } else {
-               for (pos = 0; pos < priv->firm_size; pos++) {
-                       if ((priv->firm[pos].int_freq == int_freq) &&
-                           (priv->firm[pos].type & HAS_IF))
-                               break;
-               }
-               if (pos == priv->firm_size)
-                       return -ENOENT;
-       }
-
-       p = priv->firm[pos].ptr;
-
-       if (priv->firm[pos].size != 12 * 16 || scode >= 16)
-               return -EINVAL;
-       p += 12 * scode;
-
-       if (debug) {
-               tuner_info("Loading SCODE for type=");
-               dump_firm_type_and_int_freq(priv->firm[pos].type,
-                                           priv->firm[pos].int_freq);
-               printk(KERN_CONT "(%x), id %016llx.\n", priv->firm[pos].type,
-                      (unsigned long long)*id);
-       }
-
-       scode_buf[0] = 0x00;
-       memcpy(&scode_buf[1], p, 12);
-
-       /* Enter direct-mode */
-       rc = xc_write_reg(priv, XREG_DIRECTSITTING_MODE, 0);
-       if (rc < 0) {
-               printk(KERN_ERR "failed to put device into direct mode!\n");
-               return -EIO;
-       }
-
-       rc = xc_send_i2c_data(priv, scode_buf, 13);
-       if (rc != 0) {
-               /* Even if the send failed, make sure we set back to indirect
-                  mode */
-               printk(KERN_ERR "Failed to set scode %d\n", rc);
-       }
-
-       /* Switch back to indirect-mode */
-       memset(indirect_mode, 0, sizeof(indirect_mode));
-       indirect_mode[4] = 0x88;
-       xc_send_i2c_data(priv, indirect_mode, sizeof(indirect_mode));
-       msleep(10);
-
-       return 0;
-}
-
-static int check_firmware(struct dvb_frontend *fe, unsigned int type,
-                         v4l2_std_id std, __u16 int_freq)
-{
-       struct xc4000_priv         *priv = fe->tuner_priv;
-       struct firmware_properties new_fw;
-       int                        rc = 0, is_retry = 0;
-       u16                        hwmodel;
-       v4l2_std_id                std0;
-       u8                         hw_major, hw_minor, fw_major, fw_minor;
-
-       dprintk(1, "%s called\n", __func__);
-
-       if (!priv->firm) {
-               rc = xc4000_fwupload(fe);
-               if (rc < 0)
-                       return rc;
-       }
-
-retry:
-       new_fw.type = type;
-       new_fw.id = std;
-       new_fw.std_req = std;
-       new_fw.scode_table = SCODE;
-       new_fw.scode_nr = 0;
-       new_fw.int_freq = int_freq;
-
-       dprintk(1, "checking firmware, user requested type=");
-       if (debug) {
-               dump_firm_type(new_fw.type);
-               printk(KERN_CONT "(%x), id %016llx, ", new_fw.type,
-                      (unsigned long long)new_fw.std_req);
-               if (!int_freq)
-                       printk(KERN_CONT "scode_tbl ");
-               else
-                       printk(KERN_CONT "int_freq %d, ", new_fw.int_freq);
-               printk(KERN_CONT "scode_nr %d\n", new_fw.scode_nr);
-       }
-
-       /* No need to reload base firmware if it matches */
-       if (priv->cur_fw.type & BASE) {
-               dprintk(1, "BASE firmware not changed.\n");
-               goto skip_base;
-       }
-
-       /* Updating BASE - forget about all currently loaded firmware */
-       memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
-
-       /* Reset is needed before loading firmware */
-       rc = xc4000_tuner_reset(fe);
-       if (rc < 0)
-               goto fail;
-
-       /* BASE firmwares are all std0 */
-       std0 = 0;
-       rc = load_firmware(fe, BASE, &std0);
-       if (rc < 0) {
-               printk(KERN_ERR "Error %d while loading base firmware\n", rc);
-               goto fail;
-       }
-
-       /* Load INIT1, if needed */
-       dprintk(1, "Load init1 firmware, if exists\n");
-
-       rc = load_firmware(fe, BASE | INIT1, &std0);
-       if (rc == -ENOENT)
-               rc = load_firmware(fe, BASE | INIT1, &std0);
-       if (rc < 0 && rc != -ENOENT) {
-               tuner_err("Error %d while loading init1 firmware\n",
-                         rc);
-               goto fail;
-       }
-
-skip_base:
-       /*
-        * No need to reload standard specific firmware if base firmware
-        * was not reloaded and requested video standards have not changed.
-        */
-       if (priv->cur_fw.type == (BASE | new_fw.type) &&
-           priv->cur_fw.std_req == std) {
-               dprintk(1, "Std-specific firmware already loaded.\n");
-               goto skip_std_specific;
-       }
-
-       /* Reloading std-specific firmware forces a SCODE update */
-       priv->cur_fw.scode_table = 0;
-
-       /* Load the standard firmware */
-       rc = load_firmware(fe, new_fw.type, &new_fw.id);
-
-       if (rc < 0)
-               goto fail;
-
-skip_std_specific:
-       if (priv->cur_fw.scode_table == new_fw.scode_table &&
-           priv->cur_fw.scode_nr == new_fw.scode_nr) {
-               dprintk(1, "SCODE firmware already loaded.\n");
-               goto check_device;
-       }
-
-       /* Load SCODE firmware, if exists */
-       rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id,
-                       new_fw.int_freq, new_fw.scode_nr);
-       if (rc != 0)
-               dprintk(1, "load scode failed %d\n", rc);
-
-check_device:
-       rc = xc4000_readreg(priv, XREG_PRODUCT_ID, &hwmodel);
-
-       if (xc_get_version(priv, &hw_major, &hw_minor, &fw_major,
-                          &fw_minor) != 0) {
-               printk(KERN_ERR "Unable to read tuner registers.\n");
-               goto fail;
-       }
-
-       dprintk(1, "Device is Xceive %d version %d.%d, "
-               "firmware version %d.%d\n",
-               hwmodel, hw_major, hw_minor, fw_major, fw_minor);
-
-       /* Check firmware version against what we downloaded. */
-       if (priv->firm_version != ((fw_major << 8) | fw_minor)) {
-               printk(KERN_WARNING
-                      "Incorrect readback of firmware version %d.%d.\n",
-                      fw_major, fw_minor);
-               goto fail;
-       }
-
-       /* Check that the tuner hardware model remains consistent over time. */
-       if (priv->hwmodel == 0 &&
-           (hwmodel == XC_PRODUCT_ID_XC4000 ||
-            hwmodel == XC_PRODUCT_ID_XC4100)) {
-               priv->hwmodel = hwmodel;
-               priv->hwvers = (hw_major << 8) | hw_minor;
-       } else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel ||
-                  priv->hwvers != ((hw_major << 8) | hw_minor)) {
-               printk(KERN_WARNING
-                      "Read invalid device hardware information - tuner "
-                      "hung?\n");
-               goto fail;
-       }
-
-       memcpy(&priv->cur_fw, &new_fw, sizeof(priv->cur_fw));
-
-       /*
-        * By setting BASE in cur_fw.type only after successfully loading all
-        * firmwares, we can:
-        * 1. Identify that BASE firmware with type=0 has been loaded;
-        * 2. Tell whether BASE firmware was just changed the next time through.
-        */
-       priv->cur_fw.type |= BASE;
-
-       return 0;
-
-fail:
-       memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
-       if (!is_retry) {
-               msleep(50);
-               is_retry = 1;
-               dprintk(1, "Retrying firmware load\n");
-               goto retry;
-       }
-
-       if (rc == -ENOENT)
-               rc = -EINVAL;
-       return rc;
-}
-
-static void xc_debug_dump(struct xc4000_priv *priv)
-{
-       u16     adc_envelope;
-       u32     freq_error_hz = 0;
-       u16     lock_status;
-       u32     hsync_freq_hz = 0;
-       u16     frame_lines;
-       u16     quality;
-       u16     signal = 0;
-       u16     noise = 0;
-       u8      hw_majorversion = 0, hw_minorversion = 0;
-       u8      fw_majorversion = 0, fw_minorversion = 0;
-
-       xc_get_adc_envelope(priv, &adc_envelope);
-       dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
-
-       xc_get_frequency_error(priv, &freq_error_hz);
-       dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
-
-       xc_get_lock_status(priv, &lock_status);
-       dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
-               lock_status);
-
-       xc_get_version(priv, &hw_majorversion, &hw_minorversion,
-                      &fw_majorversion, &fw_minorversion);
-       dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n",
-               hw_majorversion, hw_minorversion,
-               fw_majorversion, fw_minorversion);
-
-       if (priv->video_standard < XC4000_DTV6) {
-               xc_get_hsync_freq(priv, &hsync_freq_hz);
-               dprintk(1, "*** Horizontal sync frequency = %d Hz\n",
-                       hsync_freq_hz);
-
-               xc_get_frame_lines(priv, &frame_lines);
-               dprintk(1, "*** Frame lines = %d\n", frame_lines);
-       }
-
-       xc_get_quality(priv, &quality);
-       dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
-
-       xc_get_signal_level(priv, &signal);
-       dprintk(1, "*** Signal level = -%ddB (%d)\n", signal >> 8, signal);
-
-       xc_get_noise_level(priv, &noise);
-       dprintk(1, "*** Noise level = %ddB (%d)\n", noise >> 8, noise);
-}
-
-static int xc4000_set_params(struct dvb_frontend *fe)
-{
-       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-       u32 delsys = c->delivery_system;
-       u32 bw = c->bandwidth_hz;
-       struct xc4000_priv *priv = fe->tuner_priv;
-       unsigned int type;
-       int     ret = -EREMOTEIO;
-
-       dprintk(1, "%s() frequency=%d (Hz)\n", __func__, c->frequency);
-
-       mutex_lock(&priv->lock);
-
-       switch (delsys) {
-       case SYS_ATSC:
-               dprintk(1, "%s() VSB modulation\n", __func__);
-               priv->rf_mode = XC_RF_MODE_AIR;
-               priv->freq_hz = c->frequency - 1750000;
-               priv->video_standard = XC4000_DTV6;
-               type = DTV6;
-               break;
-       case SYS_DVBC_ANNEX_B:
-               dprintk(1, "%s() QAM modulation\n", __func__);
-               priv->rf_mode = XC_RF_MODE_CABLE;
-               priv->freq_hz = c->frequency - 1750000;
-               priv->video_standard = XC4000_DTV6;
-               type = DTV6;
-               break;
-       case SYS_DVBT:
-       case SYS_DVBT2:
-               dprintk(1, "%s() OFDM\n", __func__);
-               if (bw == 0) {
-                       if (c->frequency < 400000000) {
-                               priv->freq_hz = c->frequency - 2250000;
-                       } else {
-                               priv->freq_hz = c->frequency - 2750000;
-                       }
-                       priv->video_standard = XC4000_DTV7_8;
-                       type = DTV78;
-               } else if (bw <= 6000000) {
-                       priv->video_standard = XC4000_DTV6;
-                       priv->freq_hz = c->frequency - 1750000;
-                       type = DTV6;
-               } else if (bw <= 7000000) {
-                       priv->video_standard = XC4000_DTV7;
-                       priv->freq_hz = c->frequency - 2250000;
-                       type = DTV7;
-               } else {
-                       priv->video_standard = XC4000_DTV8;
-                       priv->freq_hz = c->frequency - 2750000;
-                       type = DTV8;
-               }
-               priv->rf_mode = XC_RF_MODE_AIR;
-               break;
-       default:
-               printk(KERN_ERR "xc4000 delivery system not supported!\n");
-               ret = -EINVAL;
-               goto fail;
-       }
-
-       dprintk(1, "%s() frequency=%d (compensated)\n",
-               __func__, priv->freq_hz);
-
-       /* Make sure the correct firmware type is loaded */
-       if (check_firmware(fe, type, 0, priv->if_khz) != 0)
-               goto fail;
-
-       priv->bandwidth = c->bandwidth_hz;
-
-       ret = xc_set_signal_source(priv, priv->rf_mode);
-       if (ret != 0) {
-               printk(KERN_ERR "xc4000: xc_set_signal_source(%d) failed\n",
-                      priv->rf_mode);
-               goto fail;
-       } else {
-               u16     video_mode, audio_mode;
-               video_mode = xc4000_standard[priv->video_standard].video_mode;
-               audio_mode = xc4000_standard[priv->video_standard].audio_mode;
-               if (type == DTV6 && priv->firm_version != 0x0102)
-                       video_mode |= 0x0001;
-               ret = xc_set_tv_standard(priv, video_mode, audio_mode);
-               if (ret != 0) {
-                       printk(KERN_ERR "xc4000: xc_set_tv_standard failed\n");
-                       /* DJH - do not return when it fails... */
-                       /* goto fail; */
-               }
-       }
-
-       if (xc_write_reg(priv, XREG_D_CODE, 0) == 0)
-               ret = 0;
-       if (priv->dvb_amplitude != 0) {
-               if (xc_write_reg(priv, XREG_AMPLITUDE,
-                                (priv->firm_version != 0x0102 ||
-                                 priv->dvb_amplitude != 134 ?
-                                 priv->dvb_amplitude : 132)) != 0)
-                       ret = -EREMOTEIO;
-       }
-       if (priv->set_smoothedcvbs != 0) {
-               if (xc_write_reg(priv, XREG_SMOOTHEDCVBS, 1) != 0)
-                       ret = -EREMOTEIO;
-       }
-       if (ret != 0) {
-               printk(KERN_ERR "xc4000: setting registers failed\n");
-               /* goto fail; */
-       }
-
-       xc_tune_channel(priv, priv->freq_hz);
-
-       ret = 0;
-
-fail:
-       mutex_unlock(&priv->lock);
-
-       return ret;
-}
-
-static int xc4000_set_analog_params(struct dvb_frontend *fe,
-       struct analog_parameters *params)
-{
-       struct xc4000_priv *priv = fe->tuner_priv;
-       unsigned int type = 0;
-       int     ret = -EREMOTEIO;
-
-       if (params->mode == V4L2_TUNER_RADIO) {
-               dprintk(1, "%s() frequency=%d (in units of 62.5Hz)\n",
-                       __func__, params->frequency);
-
-               mutex_lock(&priv->lock);
-
-               params->std = 0;
-               priv->freq_hz = params->frequency * 125L / 2;
-
-               if (audio_std & XC4000_AUDIO_STD_INPUT1) {
-                       priv->video_standard = XC4000_FM_Radio_INPUT1;
-                       type = FM | INPUT1;
-               } else {
-                       priv->video_standard = XC4000_FM_Radio_INPUT2;
-                       type = FM | INPUT2;
-               }
-
-               goto tune_channel;
-       }
-
-       dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
-               __func__, params->frequency);
-
-       mutex_lock(&priv->lock);
-
-       /* params->frequency is in units of 62.5khz */
-       priv->freq_hz = params->frequency * 62500;
-
-       params->std &= V4L2_STD_ALL;
-       /* if std is not defined, choose one */
-       if (!params->std)
-               params->std = V4L2_STD_PAL_BG;
-
-       if (audio_std & XC4000_AUDIO_STD_MONO)
-               type = MONO;
-
-       if (params->std & V4L2_STD_MN) {
-               params->std = V4L2_STD_MN;
-               if (audio_std & XC4000_AUDIO_STD_MONO) {
-                       priv->video_standard = XC4000_MN_NTSC_PAL_Mono;
-               } else if (audio_std & XC4000_AUDIO_STD_A2) {
-                       params->std |= V4L2_STD_A2;
-                       priv->video_standard = XC4000_MN_NTSC_PAL_A2;
-               } else {
-                       params->std |= V4L2_STD_BTSC;
-                       priv->video_standard = XC4000_MN_NTSC_PAL_BTSC;
-               }
-               goto tune_channel;
-       }
-
-       if (params->std & V4L2_STD_PAL_BG) {
-               params->std = V4L2_STD_PAL_BG;
-               if (audio_std & XC4000_AUDIO_STD_MONO) {
-                       priv->video_standard = XC4000_BG_PAL_MONO;
-               } else if (!(audio_std & XC4000_AUDIO_STD_A2)) {
-                       if (!(audio_std & XC4000_AUDIO_STD_B)) {
-                               params->std |= V4L2_STD_NICAM_A;
-                               priv->video_standard = XC4000_BG_PAL_NICAM;
-                       } else {
-                               params->std |= V4L2_STD_NICAM_B;
-                               priv->video_standard = XC4000_BG_PAL_NICAM;
-                       }
-               } else {
-                       if (!(audio_std & XC4000_AUDIO_STD_B)) {
-                               params->std |= V4L2_STD_A2_A;
-                               priv->video_standard = XC4000_BG_PAL_A2;
-                       } else {
-                               params->std |= V4L2_STD_A2_B;
-                               priv->video_standard = XC4000_BG_PAL_A2;
-                       }
-               }
-               goto tune_channel;
-       }
-
-       if (params->std & V4L2_STD_PAL_I) {
-               /* default to NICAM audio standard */
-               params->std = V4L2_STD_PAL_I | V4L2_STD_NICAM;
-               if (audio_std & XC4000_AUDIO_STD_MONO)
-                       priv->video_standard = XC4000_I_PAL_NICAM_MONO;
-               else
-                       priv->video_standard = XC4000_I_PAL_NICAM;
-               goto tune_channel;
-       }
-
-       if (params->std & V4L2_STD_PAL_DK) {
-               params->std = V4L2_STD_PAL_DK;
-               if (audio_std & XC4000_AUDIO_STD_MONO) {
-                       priv->video_standard = XC4000_DK_PAL_MONO;
-               } else if (audio_std & XC4000_AUDIO_STD_A2) {
-                       params->std |= V4L2_STD_A2;
-                       priv->video_standard = XC4000_DK_PAL_A2;
-               } else {
-                       params->std |= V4L2_STD_NICAM;
-                       priv->video_standard = XC4000_DK_PAL_NICAM;
-               }
-               goto tune_channel;
-       }
-
-       if (params->std & V4L2_STD_SECAM_DK) {
-               /* default to A2 audio standard */
-               params->std = V4L2_STD_SECAM_DK | V4L2_STD_A2;
-               if (audio_std & XC4000_AUDIO_STD_L) {
-                       type = 0;
-                       priv->video_standard = XC4000_DK_SECAM_NICAM;
-               } else if (audio_std & XC4000_AUDIO_STD_MONO) {
-                       priv->video_standard = XC4000_DK_SECAM_A2MONO;
-               } else if (audio_std & XC4000_AUDIO_STD_K3) {
-                       params->std |= V4L2_STD_SECAM_K3;
-                       priv->video_standard = XC4000_DK_SECAM_A2LDK3;
-               } else {
-                       priv->video_standard = XC4000_DK_SECAM_A2DK1;
-               }
-               goto tune_channel;
-       }
-
-       if (params->std & V4L2_STD_SECAM_L) {
-               /* default to NICAM audio standard */
-               type = 0;
-               params->std = V4L2_STD_SECAM_L | V4L2_STD_NICAM;
-               priv->video_standard = XC4000_L_SECAM_NICAM;
-               goto tune_channel;
-       }
-
-       if (params->std & V4L2_STD_SECAM_LC) {
-               /* default to NICAM audio standard */
-               type = 0;
-               params->std = V4L2_STD_SECAM_LC | V4L2_STD_NICAM;
-               priv->video_standard = XC4000_LC_SECAM_NICAM;
-               goto tune_channel;
-       }
-
-tune_channel:
-       /* FIXME: it could be air. */
-       priv->rf_mode = XC_RF_MODE_CABLE;
-
-       if (check_firmware(fe, type, params->std,
-                          xc4000_standard[priv->video_standard].int_freq) != 0)
-               goto fail;
-
-       ret = xc_set_signal_source(priv, priv->rf_mode);
-       if (ret != 0) {
-               printk(KERN_ERR
-                      "xc4000: xc_set_signal_source(%d) failed\n",
-                      priv->rf_mode);
-               goto fail;
-       } else {
-               u16     video_mode, audio_mode;
-               video_mode = xc4000_standard[priv->video_standard].video_mode;
-               audio_mode = xc4000_standard[priv->video_standard].audio_mode;
-               if (priv->video_standard < XC4000_BG_PAL_A2) {
-                       if (type & NOGD)
-                               video_mode &= 0xFF7F;
-               } else if (priv->video_standard < XC4000_I_PAL_NICAM) {
-                       if (priv->firm_version == 0x0102)
-                               video_mode &= 0xFEFF;
-                       if (audio_std & XC4000_AUDIO_STD_B)
-                               video_mode |= 0x0080;
-               }
-               ret = xc_set_tv_standard(priv, video_mode, audio_mode);
-               if (ret != 0) {
-                       printk(KERN_ERR "xc4000: xc_set_tv_standard failed\n");
-                       goto fail;
-               }
-       }
-
-       if (xc_write_reg(priv, XREG_D_CODE, 0) == 0)
-               ret = 0;
-       if (xc_write_reg(priv, XREG_AMPLITUDE, 1) != 0)
-               ret = -EREMOTEIO;
-       if (priv->set_smoothedcvbs != 0) {
-               if (xc_write_reg(priv, XREG_SMOOTHEDCVBS, 1) != 0)
-                       ret = -EREMOTEIO;
-       }
-       if (ret != 0) {
-               printk(KERN_ERR "xc4000: setting registers failed\n");
-               goto fail;
-       }
-
-       xc_tune_channel(priv, priv->freq_hz);
-
-       ret = 0;
-
-fail:
-       mutex_unlock(&priv->lock);
-
-       return ret;
-}
-
-static int xc4000_get_signal(struct dvb_frontend *fe, u16 *strength)
-{
-       struct xc4000_priv *priv = fe->tuner_priv;
-       u16 value = 0;
-       int rc;
-
-       mutex_lock(&priv->lock);
-       rc = xc4000_readreg(priv, XREG_SIGNAL_LEVEL, &value);
-       mutex_unlock(&priv->lock);
-
-       if (rc < 0)
-               goto ret;
-
-       /* Informations from real testing of DVB-T and radio part,
-          coeficient for one dB is 0xff.
-        */
-       tuner_dbg("Signal strength: -%ddB (%05d)\n", value >> 8, value);
-
-       /* all known digital modes */
-       if ((priv->video_standard == XC4000_DTV6) ||
-           (priv->video_standard == XC4000_DTV7) ||
-           (priv->video_standard == XC4000_DTV7_8) ||
-           (priv->video_standard == XC4000_DTV8))
-               goto digital;
-
-       /* Analog mode has NOISE LEVEL important, signal
-          depends only on gain of antenna and amplifiers,
-          but it doesn't tell anything about real quality
-          of reception.
-        */
-       mutex_lock(&priv->lock);
-       rc = xc4000_readreg(priv, XREG_NOISE_LEVEL, &value);
-       mutex_unlock(&priv->lock);
-
-       tuner_dbg("Noise level: %ddB (%05d)\n", value >> 8, value);
-
-       /* highest noise level: 32dB */
-       if (value >= 0x2000) {
-               value = 0;
-       } else {
-               value = ~value << 3;
-       }
-
-       goto ret;
-
-       /* Digital mode has SIGNAL LEVEL important and real
-          noise level is stored in demodulator registers.
-        */
-digital:
-       /* best signal: -50dB */
-       if (value <= 0x3200) {
-               value = 0xffff;
-       /* minimum: -114dB - should be 0x7200 but real zero is 0x713A */
-       } else if (value >= 0x713A) {
-               value = 0;
-       } else {
-               value = ~(value - 0x3200) << 2;
-       }
-
-ret:
-       *strength = value;
-
-       return rc;
-}
-
-static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
-{
-       struct xc4000_priv *priv = fe->tuner_priv;
-
-       *freq = priv->freq_hz;
-
-       if (debug) {
-               mutex_lock(&priv->lock);
-               if ((priv->cur_fw.type
-                    & (BASE | FM | DTV6 | DTV7 | DTV78 | DTV8)) == BASE) {
-                       u16     snr = 0;
-                       if (xc4000_readreg(priv, XREG_SNR, &snr) == 0) {
-                               mutex_unlock(&priv->lock);
-                               dprintk(1, "%s() freq = %u, SNR = %d\n",
-                                       __func__, *freq, snr);
-                               return 0;
-                       }
-               }
-               mutex_unlock(&priv->lock);
-       }
-
-       dprintk(1, "%s()\n", __func__);
-
-       return 0;
-}
-
-static int xc4000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
-{
-       struct xc4000_priv *priv = fe->tuner_priv;
-       dprintk(1, "%s()\n", __func__);
-
-       *bw = priv->bandwidth;
-       return 0;
-}
-
-static int xc4000_get_status(struct dvb_frontend *fe, u32 *status)
-{
-       struct xc4000_priv *priv = fe->tuner_priv;
-       u16     lock_status = 0;
-
-       mutex_lock(&priv->lock);
-
-       if (priv->cur_fw.type & BASE)
-               xc_get_lock_status(priv, &lock_status);
-
-       *status = (lock_status == 1 ?
-                  TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO : 0);
-       if (priv->cur_fw.type & (DTV6 | DTV7 | DTV78 | DTV8))
-               *status &= (~TUNER_STATUS_STEREO);
-
-       mutex_unlock(&priv->lock);
-
-       dprintk(2, "%s() lock_status = %d\n", __func__, lock_status);
-
-       return 0;
-}
-
-static int xc4000_sleep(struct dvb_frontend *fe)
-{
-       struct xc4000_priv *priv = fe->tuner_priv;
-       int     ret = 0;
-
-       dprintk(1, "%s()\n", __func__);
-
-       mutex_lock(&priv->lock);
-
-       /* Avoid firmware reload on slow devices */
-       if ((no_poweroff == 2 ||
-            (no_poweroff == 0 && priv->default_pm != 0)) &&
-           (priv->cur_fw.type & BASE) != 0) {
-               /* force reset and firmware reload */
-               priv->cur_fw.type = XC_POWERED_DOWN;
-
-               if (xc_write_reg(priv, XREG_POWER_DOWN, 0) != 0) {
-                       printk(KERN_ERR
-                              "xc4000: %s() unable to shutdown tuner\n",
-                              __func__);
-                       ret = -EREMOTEIO;
-               }
-               msleep(20);
-       }
-
-       mutex_unlock(&priv->lock);
-
-       return ret;
-}
-
-static int xc4000_init(struct dvb_frontend *fe)
-{
-       dprintk(1, "%s()\n", __func__);
-
-       return 0;
-}
-
-static int xc4000_release(struct dvb_frontend *fe)
-{
-       struct xc4000_priv *priv = fe->tuner_priv;
-
-       dprintk(1, "%s()\n", __func__);
-
-       mutex_lock(&xc4000_list_mutex);
-
-       if (priv)
-               hybrid_tuner_release_state(priv);
-
-       mutex_unlock(&xc4000_list_mutex);
-
-       fe->tuner_priv = NULL;
-
-       return 0;
-}
-
-static const struct dvb_tuner_ops xc4000_tuner_ops = {
-       .info = {
-               .name           = "Xceive XC4000",
-               .frequency_min  =    1000000,
-               .frequency_max  = 1023000000,
-               .frequency_step =      50000,
-       },
-
-       .release           = xc4000_release,
-       .init              = xc4000_init,
-       .sleep             = xc4000_sleep,
-
-       .set_params        = xc4000_set_params,
-       .set_analog_params = xc4000_set_analog_params,
-       .get_frequency     = xc4000_get_frequency,
-       .get_rf_strength   = xc4000_get_signal,
-       .get_bandwidth     = xc4000_get_bandwidth,
-       .get_status        = xc4000_get_status
-};
-
-struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
-                                  struct i2c_adapter *i2c,
-                                  struct xc4000_config *cfg)
-{
-       struct xc4000_priv *priv = NULL;
-       int     instance;
-       u16     id = 0;
-
-       dprintk(1, "%s(%d-%04x)\n", __func__,
-               i2c ? i2c_adapter_id(i2c) : -1,
-               cfg ? cfg->i2c_address : -1);
-
-       mutex_lock(&xc4000_list_mutex);
-
-       instance = hybrid_tuner_request_state(struct xc4000_priv, priv,
-                                             hybrid_tuner_instance_list,
-                                             i2c, cfg->i2c_address, "xc4000");
-       switch (instance) {
-       case 0:
-               goto fail;
-               break;
-       case 1:
-               /* new tuner instance */
-               priv->bandwidth = 6000000;
-               /* set default configuration */
-               priv->if_khz = 4560;
-               priv->default_pm = 0;
-               priv->dvb_amplitude = 134;
-               priv->set_smoothedcvbs = 1;
-               mutex_init(&priv->lock);
-               fe->tuner_priv = priv;
-               break;
-       default:
-               /* existing tuner instance */
-               fe->tuner_priv = priv;
-               break;
-       }
-
-       if (cfg->if_khz != 0) {
-               /* copy configuration if provided by the caller */
-               priv->if_khz = cfg->if_khz;
-               priv->default_pm = cfg->default_pm;
-               priv->dvb_amplitude = cfg->dvb_amplitude;
-               priv->set_smoothedcvbs = cfg->set_smoothedcvbs;
-       }
-
-       /* Check if firmware has been loaded. It is possible that another
-          instance of the driver has loaded the firmware.
-        */
-
-       if (instance == 1) {
-               if (xc4000_readreg(priv, XREG_PRODUCT_ID, &id) != 0)
-                       goto fail;
-       } else {
-               id = ((priv->cur_fw.type & BASE) != 0 ?
-                     priv->hwmodel : XC_PRODUCT_ID_FW_NOT_LOADED);
-       }
-
-       switch (id) {
-       case XC_PRODUCT_ID_XC4000:
-       case XC_PRODUCT_ID_XC4100:
-               printk(KERN_INFO
-                       "xc4000: Successfully identified at address 0x%02x\n",
-                       cfg->i2c_address);
-               printk(KERN_INFO
-                       "xc4000: Firmware has been loaded previously\n");
-               break;
-       case XC_PRODUCT_ID_FW_NOT_LOADED:
-               printk(KERN_INFO
-                       "xc4000: Successfully identified at address 0x%02x\n",
-                       cfg->i2c_address);
-               printk(KERN_INFO
-                       "xc4000: Firmware has not been loaded previously\n");
-               break;
-       default:
-               printk(KERN_ERR
-                       "xc4000: Device not found at addr 0x%02x (0x%x)\n",
-                       cfg->i2c_address, id);
-               goto fail;
-       }
-
-       mutex_unlock(&xc4000_list_mutex);
-
-       memcpy(&fe->ops.tuner_ops, &xc4000_tuner_ops,
-               sizeof(struct dvb_tuner_ops));
-
-       if (instance == 1) {
-               int     ret;
-               mutex_lock(&priv->lock);
-               ret = xc4000_fwupload(fe);
-               mutex_unlock(&priv->lock);
-               if (ret != 0)
-                       goto fail2;
-       }
-
-       return fe;
-fail:
-       mutex_unlock(&xc4000_list_mutex);
-fail2:
-       xc4000_release(fe);
-       return NULL;
-}
-EXPORT_SYMBOL(xc4000_attach);
-
-MODULE_AUTHOR("Steven Toth, Davide Ferri");
-MODULE_DESCRIPTION("Xceive xc4000 silicon tuner driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/xc4000.h b/drivers/media/common/tuners/xc4000.h
deleted file mode 100644 (file)
index e6a44d1..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- *  Driver for Xceive XC4000 "QAM/8VSB single chip tuner"
- *
- *  Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
- *
- *  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 __XC4000_H__
-#define __XC4000_H__
-
-#include <linux/firmware.h>
-
-struct dvb_frontend;
-struct i2c_adapter;
-
-struct xc4000_config {
-       u8      i2c_address;
-       /* if non-zero, power management is enabled by default */
-       u8      default_pm;
-       /* value to be written to XREG_AMPLITUDE in DVB-T mode (0: no write) */
-       u8      dvb_amplitude;
-       /* if non-zero, register 0x0E is set to filter analog TV video output */
-       u8      set_smoothedcvbs;
-       /* IF for DVB-T */
-       u32     if_khz;
-};
-
-/* xc4000 callback command */
-#define XC4000_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 xc4000 driver cares not for this value, other than ensuring
- * it's passed back to a bridge during tuner_callback().
- */
-
-#if defined(CONFIG_MEDIA_TUNER_XC4000) || (defined(CONFIG_MEDIA_TUNER_XC4000_MODULE) && defined(MODULE))
-extern struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
-                                         struct i2c_adapter *i2c,
-                                         struct xc4000_config *cfg);
-#else
-static inline struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
-                                                struct i2c_adapter *i2c,
-                                                struct xc4000_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
deleted file mode 100644 (file)
index dc93cf3..0000000
+++ /dev/null
@@ -1,1366 +0,0 @@
-/*
- *  Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
- *
- *  Copyright (c) 2007 Xceive Corporation
- *  Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
- *  Copyright (c) 2009 Devin Heitmueller <dheitmueller@kernellabs.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.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/videodev2.h>
-#include <linux/delay.h>
-#include <linux/dvb/frontend.h>
-#include <linux/i2c.h>
-
-#include "dvb_frontend.h"
-
-#include "xc5000.h"
-#include "tuner-i2c.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-static int no_poweroff;
-module_param(no_poweroff, int, 0644);
-MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n"
-       "\t\t1 keep device energized and with tuner ready all the times.\n"
-       "\t\tFaster, but consumes more power and keeps the device hotter");
-
-static DEFINE_MUTEX(xc5000_list_mutex);
-static LIST_HEAD(hybrid_tuner_instance_list);
-
-#define dprintk(level, fmt, arg...) if (debug >= level) \
-       printk(KERN_INFO "%s: " fmt, "xc5000", ## arg)
-
-struct xc5000_priv {
-       struct tuner_i2c_props i2c_props;
-       struct list_head hybrid_tuner_instance_list;
-
-       u32 if_khz;
-       u16 xtal_khz;
-       u32 freq_hz;
-       u32 bandwidth;
-       u8  video_standard;
-       u8  rf_mode;
-       u8  radio_input;
-
-       int chip_id;
-       u16 pll_register_no;
-       u8 init_status_supported;
-       u8 fw_checksum_supported;
-};
-
-/* Misc Defines */
-#define MAX_TV_STANDARD                        24
-#define XC_MAX_I2C_WRITE_LENGTH                64
-
-/* Signal Types */
-#define XC_RF_MODE_AIR                 0
-#define XC_RF_MODE_CABLE               1
-
-/* Result codes */
-#define XC_RESULT_SUCCESS              0
-#define XC_RESULT_RESET_FAILURE                1
-#define XC_RESULT_I2C_WRITE_FAILURE    2
-#define XC_RESULT_I2C_READ_FAILURE     3
-#define XC_RESULT_OUT_OF_RANGE         5
-
-/* Product id */
-#define XC_PRODUCT_ID_FW_NOT_LOADED    0x2000
-#define XC_PRODUCT_ID_FW_LOADED        0x1388
-
-/* Registers */
-#define XREG_INIT         0x00
-#define XREG_VIDEO_MODE   0x01
-#define XREG_AUDIO_MODE   0x02
-#define XREG_RF_FREQ      0x03
-#define XREG_D_CODE       0x04
-#define XREG_IF_OUT       0x05
-#define XREG_SEEK_MODE    0x07
-#define XREG_POWER_DOWN   0x0A /* Obsolete */
-/* Set the output amplitude - SIF for analog, DTVP/DTVN for digital */
-#define XREG_OUTPUT_AMP   0x0B
-#define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */
-#define XREG_SMOOTHEDCVBS 0x0E
-#define XREG_XTALFREQ     0x0F
-#define XREG_FINERFREQ    0x10
-#define XREG_DDIMODE      0x11
-
-#define XREG_ADC_ENV      0x00
-#define XREG_QUALITY      0x01
-#define XREG_FRAME_LINES  0x02
-#define XREG_HSYNC_FREQ   0x03
-#define XREG_LOCK         0x04
-#define XREG_FREQ_ERROR   0x05
-#define XREG_SNR          0x06
-#define XREG_VERSION      0x07
-#define XREG_PRODUCT_ID   0x08
-#define XREG_BUSY         0x09
-#define XREG_BUILD        0x0D
-#define XREG_TOTALGAIN    0x0F
-#define XREG_FW_CHECKSUM  0x12
-#define XREG_INIT_STATUS  0x13
-
-/*
-   Basic firmware description. This will remain with
-   the driver for documentation purposes.
-
-   This represents an I2C firmware file encoded as a
-   string of unsigned char. Format is as follows:
-
-   char[0  ]=len0_MSB  -> len = len_MSB * 256 + len_LSB
-   char[1  ]=len0_LSB  -> length of first write transaction
-   char[2  ]=data0 -> first byte to be sent
-   char[3  ]=data1
-   char[4  ]=data2
-   char[   ]=...
-   char[M  ]=dataN  -> last byte to be sent
-   char[M+1]=len1_MSB  -> len = len_MSB * 256 + len_LSB
-   char[M+2]=len1_LSB  -> length of second write transaction
-   char[M+3]=data0
-   char[M+4]=data1
-   ...
-   etc.
-
-   The [len] value should be interpreted as follows:
-
-   len= len_MSB _ len_LSB
-   len=1111_1111_1111_1111   : End of I2C_SEQUENCE
-   len=0000_0000_0000_0000   : Reset command: Do hardware reset
-   len=0NNN_NNNN_NNNN_NNNN   : Normal transaction: number of bytes = {1:32767)
-   len=1WWW_WWWW_WWWW_WWWW   : Wait command: wait for {1:32767} ms
-
-   For the RESET and WAIT commands, the two following bytes will contain
-   immediately the length of the following transaction.
-
-*/
-struct XC_TV_STANDARD {
-       char *Name;
-       u16 AudioMode;
-       u16 VideoMode;
-};
-
-/* Tuner standards */
-#define MN_NTSC_PAL_BTSC       0
-#define MN_NTSC_PAL_A2         1
-#define MN_NTSC_PAL_EIAJ       2
-#define MN_NTSC_PAL_Mono       3
-#define BG_PAL_A2              4
-#define BG_PAL_NICAM           5
-#define BG_PAL_MONO            6
-#define I_PAL_NICAM            7
-#define I_PAL_NICAM_MONO       8
-#define DK_PAL_A2              9
-#define DK_PAL_NICAM           10
-#define DK_PAL_MONO            11
-#define DK_SECAM_A2DK1         12
-#define DK_SECAM_A2LDK3        13
-#define DK_SECAM_A2MONO        14
-#define L_SECAM_NICAM          15
-#define LC_SECAM_NICAM         16
-#define DTV6                   17
-#define DTV8                   18
-#define DTV7_8                 19
-#define DTV7                   20
-#define FM_Radio_INPUT2        21
-#define FM_Radio_INPUT1        22
-#define FM_Radio_INPUT1_MONO   23
-
-static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
-       {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020},
-       {"M/N-NTSC/PAL-A2",   0x0600, 0x8020},
-       {"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020},
-       {"M/N-NTSC/PAL-Mono", 0x0478, 0x8020},
-       {"B/G-PAL-A2",        0x0A00, 0x8049},
-       {"B/G-PAL-NICAM",     0x0C04, 0x8049},
-       {"B/G-PAL-MONO",      0x0878, 0x8059},
-       {"I-PAL-NICAM",       0x1080, 0x8009},
-       {"I-PAL-NICAM-MONO",  0x0E78, 0x8009},
-       {"D/K-PAL-A2",        0x1600, 0x8009},
-       {"D/K-PAL-NICAM",     0x0E80, 0x8009},
-       {"D/K-PAL-MONO",      0x1478, 0x8009},
-       {"D/K-SECAM-A2 DK1",  0x1200, 0x8009},
-       {"D/K-SECAM-A2 L/DK3", 0x0E00, 0x8009},
-       {"D/K-SECAM-A2 MONO", 0x1478, 0x8009},
-       {"L-SECAM-NICAM",     0x8E82, 0x0009},
-       {"L'-SECAM-NICAM",    0x8E82, 0x4009},
-       {"DTV6",              0x00C0, 0x8002},
-       {"DTV8",              0x00C0, 0x800B},
-       {"DTV7/8",            0x00C0, 0x801B},
-       {"DTV7",              0x00C0, 0x8007},
-       {"FM Radio-INPUT2",   0x9802, 0x9002},
-       {"FM Radio-INPUT1",   0x0208, 0x9002},
-       {"FM Radio-INPUT1_MONO", 0x0278, 0x9002}
-};
-
-
-struct xc5000_fw_cfg {
-       char *name;
-       u16 size;
-       u16 pll_reg;
-       u8 init_status_supported;
-       u8 fw_checksum_supported;
-};
-
-#define XC5000A_FIRMWARE "dvb-fe-xc5000-1.6.114.fw"
-static const struct xc5000_fw_cfg xc5000a_1_6_114 = {
-       .name = XC5000A_FIRMWARE,
-       .size = 12401,
-       .pll_reg = 0x806c,
-};
-
-#define XC5000C_FIRMWARE "dvb-fe-xc5000c-4.1.30.7.fw"
-static const struct xc5000_fw_cfg xc5000c_41_024_5 = {
-       .name = XC5000C_FIRMWARE,
-       .size = 16497,
-       .pll_reg = 0x13,
-       .init_status_supported = 1,
-       .fw_checksum_supported = 1,
-};
-
-static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id)
-{
-       switch (chip_id) {
-       default:
-       case XC5000A:
-               return &xc5000a_1_6_114;
-       case XC5000C:
-               return &xc5000c_41_024_5;
-       }
-}
-
-static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force);
-static int xc5000_is_firmware_loaded(struct dvb_frontend *fe);
-static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val);
-static int xc5000_TunerReset(struct dvb_frontend *fe);
-
-static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
-{
-       struct i2c_msg msg = { .addr = priv->i2c_props.addr,
-                              .flags = 0, .buf = buf, .len = len };
-
-       if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
-               printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n", len);
-               return XC_RESULT_I2C_WRITE_FAILURE;
-       }
-       return XC_RESULT_SUCCESS;
-}
-
-#if 0
-/* This routine is never used because the only time we read data from the
-   i2c bus is when we read registers, and we want that to be an atomic i2c
-   transaction in case we are on a multi-master bus */
-static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
-{
-       struct i2c_msg msg = { .addr = priv->i2c_props.addr,
-               .flags = I2C_M_RD, .buf = buf, .len = len };
-
-       if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
-               printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", len);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-#endif
-
-static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val)
-{
-       u8 buf[2] = { reg >> 8, reg & 0xff };
-       u8 bval[2] = { 0, 0 };
-       struct i2c_msg msg[2] = {
-               { .addr = priv->i2c_props.addr,
-                       .flags = 0, .buf = &buf[0], .len = 2 },
-               { .addr = priv->i2c_props.addr,
-                       .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
-       };
-
-       if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
-               printk(KERN_WARNING "xc5000: I2C read failed\n");
-               return -EREMOTEIO;
-       }
-
-       *val = (bval[0] << 8) | bval[1];
-       return XC_RESULT_SUCCESS;
-}
-
-static void xc_wait(int wait_ms)
-{
-       msleep(wait_ms);
-}
-
-static int xc5000_TunerReset(struct dvb_frontend *fe)
-{
-       struct xc5000_priv *priv = fe->tuner_priv;
-       int ret;
-
-       dprintk(1, "%s()\n", __func__);
-
-       if (fe->callback) {
-               ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
-                                          fe->dvb->priv :
-                                          priv->i2c_props.adap->algo_data,
-                                          DVB_FRONTEND_COMPONENT_TUNER,
-                                          XC5000_TUNER_RESET, 0);
-               if (ret) {
-                       printk(KERN_ERR "xc5000: reset failed\n");
-                       return XC_RESULT_RESET_FAILURE;
-               }
-       } else {
-               printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n");
-               return XC_RESULT_RESET_FAILURE;
-       }
-       return XC_RESULT_SUCCESS;
-}
-
-static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData)
-{
-       u8 buf[4];
-       int WatchDogTimer = 100;
-       int result;
-
-       buf[0] = (regAddr >> 8) & 0xFF;
-       buf[1] = regAddr & 0xFF;
-       buf[2] = (i2cData >> 8) & 0xFF;
-       buf[3] = i2cData & 0xFF;
-       result = xc_send_i2c_data(priv, buf, 4);
-       if (result == XC_RESULT_SUCCESS) {
-               /* wait for busy flag to clear */
-               while ((WatchDogTimer > 0) && (result == XC_RESULT_SUCCESS)) {
-                       result = xc5000_readreg(priv, XREG_BUSY, (u16 *)buf);
-                       if (result == XC_RESULT_SUCCESS) {
-                               if ((buf[0] == 0) && (buf[1] == 0)) {
-                                       /* busy flag cleared */
-                                       break;
-                               } else {
-                                       xc_wait(5); /* wait 5 ms */
-                                       WatchDogTimer--;
-                               }
-                       }
-               }
-       }
-       if (WatchDogTimer <= 0)
-               result = XC_RESULT_I2C_WRITE_FAILURE;
-
-       return result;
-}
-
-static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
-{
-       struct xc5000_priv *priv = fe->tuner_priv;
-
-       int i, nbytes_to_send, result;
-       unsigned int len, pos, index;
-       u8 buf[XC_MAX_I2C_WRITE_LENGTH];
-
-       index = 0;
-       while ((i2c_sequence[index] != 0xFF) ||
-               (i2c_sequence[index + 1] != 0xFF)) {
-               len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
-               if (len == 0x0000) {
-                       /* RESET command */
-                       result = xc5000_TunerReset(fe);
-                       index += 2;
-                       if (result != XC_RESULT_SUCCESS)
-                               return result;
-               } else if (len & 0x8000) {
-                       /* WAIT command */
-                       xc_wait(len & 0x7FFF);
-                       index += 2;
-               } else {
-                       /* Send i2c data whilst ensuring individual transactions
-                        * do not exceed XC_MAX_I2C_WRITE_LENGTH bytes.
-                        */
-                       index += 2;
-                       buf[0] = i2c_sequence[index];
-                       buf[1] = i2c_sequence[index + 1];
-                       pos = 2;
-                       while (pos < len) {
-                               if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
-                                       nbytes_to_send =
-                                               XC_MAX_I2C_WRITE_LENGTH;
-                               else
-                                       nbytes_to_send = (len - pos + 2);
-                               for (i = 2; i < nbytes_to_send; i++) {
-                                       buf[i] = i2c_sequence[index + pos +
-                                               i - 2];
-                               }
-                               result = xc_send_i2c_data(priv, buf,
-                                       nbytes_to_send);
-
-                               if (result != XC_RESULT_SUCCESS)
-                                       return result;
-
-                               pos += nbytes_to_send - 2;
-                       }
-                       index += len;
-               }
-       }
-       return XC_RESULT_SUCCESS;
-}
-
-static int xc_initialize(struct xc5000_priv *priv)
-{
-       dprintk(1, "%s()\n", __func__);
-       return xc_write_reg(priv, XREG_INIT, 0);
-}
-
-static int xc_SetTVStandard(struct xc5000_priv *priv,
-       u16 VideoMode, u16 AudioMode)
-{
-       int ret;
-       dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, VideoMode, AudioMode);
-       dprintk(1, "%s() Standard = %s\n",
-               __func__,
-               XC5000_Standard[priv->video_standard].Name);
-
-       ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode);
-       if (ret == XC_RESULT_SUCCESS)
-               ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode);
-
-       return ret;
-}
-
-static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode)
-{
-       dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
-               rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
-
-       if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
-               rf_mode = XC_RF_MODE_CABLE;
-               printk(KERN_ERR
-                       "%s(), Invalid mode, defaulting to CABLE",
-                       __func__);
-       }
-       return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
-}
-
-static const struct dvb_tuner_ops xc5000_tuner_ops;
-
-static int xc_set_RF_frequency(struct xc5000_priv *priv, u32 freq_hz)
-{
-       u16 freq_code;
-
-       dprintk(1, "%s(%u)\n", __func__, freq_hz);
-
-       if ((freq_hz > xc5000_tuner_ops.info.frequency_max) ||
-               (freq_hz < xc5000_tuner_ops.info.frequency_min))
-               return XC_RESULT_OUT_OF_RANGE;
-
-       freq_code = (u16)(freq_hz / 15625);
-
-       /* Starting in firmware version 1.1.44, Xceive recommends using the
-          FINERFREQ for all normal tuning (the doc indicates reg 0x03 should
-          only be used for fast scanning for channel lock) */
-       return xc_write_reg(priv, XREG_FINERFREQ, freq_code);
-}
-
-
-static int xc_set_IF_frequency(struct xc5000_priv *priv, u32 freq_khz)
-{
-       u32 freq_code = (freq_khz * 1024)/1000;
-       dprintk(1, "%s(freq_khz = %d) freq_code = 0x%x\n",
-               __func__, freq_khz, freq_code);
-
-       return xc_write_reg(priv, XREG_IF_OUT, freq_code);
-}
-
-
-static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope)
-{
-       return xc5000_readreg(priv, XREG_ADC_ENV, adc_envelope);
-}
-
-static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz)
-{
-       int result;
-       u16 regData;
-       u32 tmp;
-
-       result = xc5000_readreg(priv, XREG_FREQ_ERROR, &regData);
-       if (result != XC_RESULT_SUCCESS)
-               return result;
-
-       tmp = (u32)regData;
-       (*freq_error_hz) = (tmp * 15625) / 1000;
-       return result;
-}
-
-static int xc_get_lock_status(struct xc5000_priv *priv, u16 *lock_status)
-{
-       return xc5000_readreg(priv, XREG_LOCK, lock_status);
-}
-
-static int xc_get_version(struct xc5000_priv *priv,
-       u8 *hw_majorversion, u8 *hw_minorversion,
-       u8 *fw_majorversion, u8 *fw_minorversion)
-{
-       u16 data;
-       int result;
-
-       result = xc5000_readreg(priv, XREG_VERSION, &data);
-       if (result != XC_RESULT_SUCCESS)
-               return result;
-
-       (*hw_majorversion) = (data >> 12) & 0x0F;
-       (*hw_minorversion) = (data >>  8) & 0x0F;
-       (*fw_majorversion) = (data >>  4) & 0x0F;
-       (*fw_minorversion) = data & 0x0F;
-
-       return 0;
-}
-
-static int xc_get_buildversion(struct xc5000_priv *priv, u16 *buildrev)
-{
-       return xc5000_readreg(priv, XREG_BUILD, buildrev);
-}
-
-static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz)
-{
-       u16 regData;
-       int result;
-
-       result = xc5000_readreg(priv, XREG_HSYNC_FREQ, &regData);
-       if (result != XC_RESULT_SUCCESS)
-               return result;
-
-       (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
-       return result;
-}
-
-static int xc_get_frame_lines(struct xc5000_priv *priv, u16 *frame_lines)
-{
-       return xc5000_readreg(priv, XREG_FRAME_LINES, frame_lines);
-}
-
-static int xc_get_quality(struct xc5000_priv *priv, u16 *quality)
-{
-       return xc5000_readreg(priv, XREG_QUALITY, quality);
-}
-
-static int xc_get_analogsnr(struct xc5000_priv *priv, u16 *snr)
-{
-       return xc5000_readreg(priv, XREG_SNR, snr);
-}
-
-static int xc_get_totalgain(struct xc5000_priv *priv, u16 *totalgain)
-{
-       return xc5000_readreg(priv, XREG_TOTALGAIN, totalgain);
-}
-
-static u16 WaitForLock(struct xc5000_priv *priv)
-{
-       u16 lockState = 0;
-       int watchDogCount = 40;
-
-       while ((lockState == 0) && (watchDogCount > 0)) {
-               xc_get_lock_status(priv, &lockState);
-               if (lockState != 1) {
-                       xc_wait(5);
-                       watchDogCount--;
-               }
-       }
-       return lockState;
-}
-
-#define XC_TUNE_ANALOG  0
-#define XC_TUNE_DIGITAL 1
-static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode)
-{
-       int found = 0;
-
-       dprintk(1, "%s(%u)\n", __func__, freq_hz);
-
-       if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS)
-               return 0;
-
-       if (mode == XC_TUNE_ANALOG) {
-               if (WaitForLock(priv) == 1)
-                       found = 1;
-       }
-
-       return found;
-}
-
-static int xc_set_xtal(struct dvb_frontend *fe)
-{
-       struct xc5000_priv *priv = fe->tuner_priv;
-       int ret = XC_RESULT_SUCCESS;
-
-       switch (priv->chip_id) {
-       default:
-       case XC5000A:
-               /* 32.000 MHz xtal is default */
-               break;
-       case XC5000C:
-               switch (priv->xtal_khz) {
-               default:
-               case 32000:
-                       /* 32.000 MHz xtal is default */
-                       break;
-               case 31875:
-                       /* 31.875 MHz xtal configuration */
-                       ret = xc_write_reg(priv, 0x000f, 0x8081);
-                       break;
-               }
-               break;
-       }
-       return ret;
-}
-
-static int xc5000_fwupload(struct dvb_frontend *fe)
-{
-       struct xc5000_priv *priv = fe->tuner_priv;
-       const struct firmware *fw;
-       int ret;
-       const struct xc5000_fw_cfg *desired_fw =
-               xc5000_assign_firmware(priv->chip_id);
-       priv->pll_register_no = desired_fw->pll_reg;
-       priv->init_status_supported = desired_fw->init_status_supported;
-       priv->fw_checksum_supported = desired_fw->fw_checksum_supported;
-
-       /* request the firmware, this will block and timeout */
-       printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
-               desired_fw->name);
-
-       ret = request_firmware(&fw, desired_fw->name,
-               priv->i2c_props.adap->dev.parent);
-       if (ret) {
-               printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
-               ret = XC_RESULT_RESET_FAILURE;
-               goto out;
-       } else {
-               printk(KERN_DEBUG "xc5000: firmware read %Zu bytes.\n",
-                      fw->size);
-               ret = XC_RESULT_SUCCESS;
-       }
-
-       if (fw->size != desired_fw->size) {
-               printk(KERN_ERR "xc5000: firmware incorrect size\n");
-               ret = XC_RESULT_RESET_FAILURE;
-       } else {
-               printk(KERN_INFO "xc5000: firmware uploading...\n");
-               ret = xc_load_i2c_sequence(fe,  fw->data);
-               if (XC_RESULT_SUCCESS == ret)
-                       ret = xc_set_xtal(fe);
-               if (XC_RESULT_SUCCESS == ret)
-                       printk(KERN_INFO "xc5000: firmware upload complete...\n");
-               else
-                       printk(KERN_ERR "xc5000: firmware upload failed...\n");
-       }
-
-out:
-       release_firmware(fw);
-       return ret;
-}
-
-static void xc_debug_dump(struct xc5000_priv *priv)
-{
-       u16 adc_envelope;
-       u32 freq_error_hz = 0;
-       u16 lock_status;
-       u32 hsync_freq_hz = 0;
-       u16 frame_lines;
-       u16 quality;
-       u16 snr;
-       u16 totalgain;
-       u8 hw_majorversion = 0, hw_minorversion = 0;
-       u8 fw_majorversion = 0, fw_minorversion = 0;
-       u16 fw_buildversion = 0;
-       u16 regval;
-
-       /* Wait for stats to stabilize.
-        * Frame Lines needs two frame times after initial lock
-        * before it is valid.
-        */
-       xc_wait(100);
-
-       xc_get_ADC_Envelope(priv,  &adc_envelope);
-       dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
-
-       xc_get_frequency_error(priv, &freq_error_hz);
-       dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
-
-       xc_get_lock_status(priv,  &lock_status);
-       dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
-               lock_status);
-
-       xc_get_version(priv,  &hw_majorversion, &hw_minorversion,
-               &fw_majorversion, &fw_minorversion);
-       xc_get_buildversion(priv,  &fw_buildversion);
-       dprintk(1, "*** HW: V%d.%d, FW: V %d.%d.%d\n",
-               hw_majorversion, hw_minorversion,
-               fw_majorversion, fw_minorversion, fw_buildversion);
-
-       xc_get_hsync_freq(priv,  &hsync_freq_hz);
-       dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz);
-
-       xc_get_frame_lines(priv,  &frame_lines);
-       dprintk(1, "*** Frame lines = %d\n", frame_lines);
-
-       xc_get_quality(priv,  &quality);
-       dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality & 0x07);
-
-       xc_get_analogsnr(priv,  &snr);
-       dprintk(1, "*** Unweighted analog SNR = %d dB\n", snr & 0x3f);
-
-       xc_get_totalgain(priv,  &totalgain);
-       dprintk(1, "*** Total gain = %d.%d dB\n", totalgain / 256,
-               (totalgain % 256) * 100 / 256);
-
-       if (priv->pll_register_no) {
-               xc5000_readreg(priv, priv->pll_register_no, &regval);
-               dprintk(1, "*** PLL lock status = 0x%04x\n", regval);
-       }
-}
-
-static int xc5000_set_params(struct dvb_frontend *fe)
-{
-       int ret, b;
-       struct xc5000_priv *priv = fe->tuner_priv;
-       u32 bw = fe->dtv_property_cache.bandwidth_hz;
-       u32 freq = fe->dtv_property_cache.frequency;
-       u32 delsys  = fe->dtv_property_cache.delivery_system;
-
-       if (xc_load_fw_and_init_tuner(fe, 0) != XC_RESULT_SUCCESS) {
-               dprintk(1, "Unable to load firmware and init tuner\n");
-               return -EINVAL;
-       }
-
-       dprintk(1, "%s() frequency=%d (Hz)\n", __func__, freq);
-
-       switch (delsys) {
-       case SYS_ATSC:
-               dprintk(1, "%s() VSB modulation\n", __func__);
-               priv->rf_mode = XC_RF_MODE_AIR;
-               priv->freq_hz = freq - 1750000;
-               priv->video_standard = DTV6;
-               break;
-       case SYS_DVBC_ANNEX_B:
-               dprintk(1, "%s() QAM modulation\n", __func__);
-               priv->rf_mode = XC_RF_MODE_CABLE;
-               priv->freq_hz = freq - 1750000;
-               priv->video_standard = DTV6;
-               break;
-       case SYS_ISDBT:
-               /* All ISDB-T are currently for 6 MHz bw */
-               if (!bw)
-                       bw = 6000000;
-               /* fall to OFDM handling */
-       case SYS_DMBTH:
-       case SYS_DVBT:
-       case SYS_DVBT2:
-               dprintk(1, "%s() OFDM\n", __func__);
-               switch (bw) {
-               case 6000000:
-                       priv->video_standard = DTV6;
-                       priv->freq_hz = freq - 1750000;
-                       break;
-               case 7000000:
-                       priv->video_standard = DTV7;
-                       priv->freq_hz = freq - 2250000;
-                       break;
-               case 8000000:
-                       priv->video_standard = DTV8;
-                       priv->freq_hz = freq - 2750000;
-                       break;
-               default:
-                       printk(KERN_ERR "xc5000 bandwidth not set!\n");
-                       return -EINVAL;
-               }
-               priv->rf_mode = XC_RF_MODE_AIR;
-       case SYS_DVBC_ANNEX_A:
-       case SYS_DVBC_ANNEX_C:
-               dprintk(1, "%s() QAM modulation\n", __func__);
-               priv->rf_mode = XC_RF_MODE_CABLE;
-               if (bw <= 6000000) {
-                       priv->video_standard = DTV6;
-                       priv->freq_hz = freq - 1750000;
-                       b = 6;
-               } else if (bw <= 7000000) {
-                       priv->video_standard = DTV7;
-                       priv->freq_hz = freq - 2250000;
-                       b = 7;
-               } else {
-                       priv->video_standard = DTV7_8;
-                       priv->freq_hz = freq - 2750000;
-                       b = 8;
-               }
-               dprintk(1, "%s() Bandwidth %dMHz (%d)\n", __func__,
-                       b, bw);
-               break;
-       default:
-               printk(KERN_ERR "xc5000: delivery system is not supported!\n");
-               return -EINVAL;
-       }
-
-       dprintk(1, "%s() frequency=%d (compensated to %d)\n",
-               __func__, freq, priv->freq_hz);
-
-       ret = xc_SetSignalSource(priv, priv->rf_mode);
-       if (ret != XC_RESULT_SUCCESS) {
-               printk(KERN_ERR
-                       "xc5000: xc_SetSignalSource(%d) failed\n",
-                       priv->rf_mode);
-               return -EREMOTEIO;
-       }
-
-       ret = xc_SetTVStandard(priv,
-               XC5000_Standard[priv->video_standard].VideoMode,
-               XC5000_Standard[priv->video_standard].AudioMode);
-       if (ret != XC_RESULT_SUCCESS) {
-               printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
-               return -EREMOTEIO;
-       }
-
-       ret = xc_set_IF_frequency(priv, priv->if_khz);
-       if (ret != XC_RESULT_SUCCESS) {
-               printk(KERN_ERR "xc5000: xc_Set_IF_frequency(%d) failed\n",
-                      priv->if_khz);
-               return -EIO;
-       }
-
-       xc_write_reg(priv, XREG_OUTPUT_AMP, 0x8a);
-
-       xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
-
-       if (debug)
-               xc_debug_dump(priv);
-
-       priv->bandwidth = bw;
-
-       return 0;
-}
-
-static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
-{
-       struct xc5000_priv *priv = fe->tuner_priv;
-       int ret;
-       u16 id;
-
-       ret = xc5000_readreg(priv, XREG_PRODUCT_ID, &id);
-       if (ret == XC_RESULT_SUCCESS) {
-               if (id == XC_PRODUCT_ID_FW_NOT_LOADED)
-                       ret = XC_RESULT_RESET_FAILURE;
-               else
-                       ret = XC_RESULT_SUCCESS;
-       }
-
-       dprintk(1, "%s() returns %s id = 0x%x\n", __func__,
-               ret == XC_RESULT_SUCCESS ? "True" : "False", id);
-       return ret;
-}
-
-static int xc5000_set_tv_freq(struct dvb_frontend *fe,
-       struct analog_parameters *params)
-{
-       struct xc5000_priv *priv = fe->tuner_priv;
-       u16 pll_lock_status;
-       int ret;
-
-       dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
-               __func__, params->frequency);
-
-       /* Fix me: it could be air. */
-       priv->rf_mode = params->mode;
-       if (params->mode > XC_RF_MODE_CABLE)
-               priv->rf_mode = XC_RF_MODE_CABLE;
-
-       /* params->frequency is in units of 62.5khz */
-       priv->freq_hz = params->frequency * 62500;
-
-       /* FIX ME: Some video standards may have several possible audio
-                  standards. We simply default to one of them here.
-        */
-       if (params->std & V4L2_STD_MN) {
-               /* default to BTSC audio standard */
-               priv->video_standard = MN_NTSC_PAL_BTSC;
-               goto tune_channel;
-       }
-
-       if (params->std & V4L2_STD_PAL_BG) {
-               /* default to NICAM audio standard */
-               priv->video_standard = BG_PAL_NICAM;
-               goto tune_channel;
-       }
-
-       if (params->std & V4L2_STD_PAL_I) {
-               /* default to NICAM audio standard */
-               priv->video_standard = I_PAL_NICAM;
-               goto tune_channel;
-       }
-
-       if (params->std & V4L2_STD_PAL_DK) {
-               /* default to NICAM audio standard */
-               priv->video_standard = DK_PAL_NICAM;
-               goto tune_channel;
-       }
-
-       if (params->std & V4L2_STD_SECAM_DK) {
-               /* default to A2 DK1 audio standard */
-               priv->video_standard = DK_SECAM_A2DK1;
-               goto tune_channel;
-       }
-
-       if (params->std & V4L2_STD_SECAM_L) {
-               priv->video_standard = L_SECAM_NICAM;
-               goto tune_channel;
-       }
-
-       if (params->std & V4L2_STD_SECAM_LC) {
-               priv->video_standard = LC_SECAM_NICAM;
-               goto tune_channel;
-       }
-
-tune_channel:
-       ret = xc_SetSignalSource(priv, priv->rf_mode);
-       if (ret != XC_RESULT_SUCCESS) {
-               printk(KERN_ERR
-                       "xc5000: xc_SetSignalSource(%d) failed\n",
-                       priv->rf_mode);
-               return -EREMOTEIO;
-       }
-
-       ret = xc_SetTVStandard(priv,
-               XC5000_Standard[priv->video_standard].VideoMode,
-               XC5000_Standard[priv->video_standard].AudioMode);
-       if (ret != XC_RESULT_SUCCESS) {
-               printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
-               return -EREMOTEIO;
-       }
-
-       xc_write_reg(priv, XREG_OUTPUT_AMP, 0x09);
-
-       xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
-
-       if (debug)
-               xc_debug_dump(priv);
-
-       if (priv->pll_register_no != 0) {
-               msleep(20);
-               xc5000_readreg(priv, priv->pll_register_no, &pll_lock_status);
-               if (pll_lock_status > 63) {
-                       /* PLL is unlocked, force reload of the firmware */
-                       dprintk(1, "xc5000: PLL not locked (0x%x).  Reloading...\n",
-                               pll_lock_status);
-                       if (xc_load_fw_and_init_tuner(fe, 1) != XC_RESULT_SUCCESS) {
-                               printk(KERN_ERR "xc5000: Unable to reload fw\n");
-                               return -EREMOTEIO;
-                       }
-                       goto tune_channel;
-               }
-       }
-
-       return 0;
-}
-
-static int xc5000_set_radio_freq(struct dvb_frontend *fe,
-       struct analog_parameters *params)
-{
-       struct xc5000_priv *priv = fe->tuner_priv;
-       int ret = -EINVAL;
-       u8 radio_input;
-
-       dprintk(1, "%s() frequency=%d (in units of khz)\n",
-               __func__, params->frequency);
-
-       if (priv->radio_input == XC5000_RADIO_NOT_CONFIGURED) {
-               dprintk(1, "%s() radio input not configured\n", __func__);
-               return -EINVAL;
-       }
-
-       if (priv->radio_input == XC5000_RADIO_FM1)
-               radio_input = FM_Radio_INPUT1;
-       else if  (priv->radio_input == XC5000_RADIO_FM2)
-               radio_input = FM_Radio_INPUT2;
-       else if  (priv->radio_input == XC5000_RADIO_FM1_MONO)
-               radio_input = FM_Radio_INPUT1_MONO;
-       else {
-               dprintk(1, "%s() unknown radio input %d\n", __func__,
-                       priv->radio_input);
-               return -EINVAL;
-       }
-
-       priv->freq_hz = params->frequency * 125 / 2;
-
-       priv->rf_mode = XC_RF_MODE_AIR;
-
-       ret = xc_SetTVStandard(priv, XC5000_Standard[radio_input].VideoMode,
-                              XC5000_Standard[radio_input].AudioMode);
-
-       if (ret != XC_RESULT_SUCCESS) {
-               printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
-               return -EREMOTEIO;
-       }
-
-       ret = xc_SetSignalSource(priv, priv->rf_mode);
-       if (ret != XC_RESULT_SUCCESS) {
-               printk(KERN_ERR
-                       "xc5000: xc_SetSignalSource(%d) failed\n",
-                       priv->rf_mode);
-               return -EREMOTEIO;
-       }
-
-       if ((priv->radio_input == XC5000_RADIO_FM1) ||
-                               (priv->radio_input == XC5000_RADIO_FM2))
-               xc_write_reg(priv, XREG_OUTPUT_AMP, 0x09);
-       else if  (priv->radio_input == XC5000_RADIO_FM1_MONO)
-               xc_write_reg(priv, XREG_OUTPUT_AMP, 0x06);
-
-       xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
-
-       return 0;
-}
-
-static int xc5000_set_analog_params(struct dvb_frontend *fe,
-                            struct analog_parameters *params)
-{
-       struct xc5000_priv *priv = fe->tuner_priv;
-       int ret = -EINVAL;
-
-       if (priv->i2c_props.adap == NULL)
-               return -EINVAL;
-
-       if (xc_load_fw_and_init_tuner(fe, 0) != XC_RESULT_SUCCESS) {
-               dprintk(1, "Unable to load firmware and init tuner\n");
-               return -EINVAL;
-       }
-
-       switch (params->mode) {
-       case V4L2_TUNER_RADIO:
-               ret = xc5000_set_radio_freq(fe, params);
-               break;
-       case V4L2_TUNER_ANALOG_TV:
-       case V4L2_TUNER_DIGITAL_TV:
-               ret = xc5000_set_tv_freq(fe, params);
-               break;
-       }
-
-       return ret;
-}
-
-
-static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq)
-{
-       struct xc5000_priv *priv = fe->tuner_priv;
-       dprintk(1, "%s()\n", __func__);
-       *freq = priv->freq_hz;
-       return 0;
-}
-
-static int xc5000_get_if_frequency(struct dvb_frontend *fe, u32 *freq)
-{
-       struct xc5000_priv *priv = fe->tuner_priv;
-       dprintk(1, "%s()\n", __func__);
-       *freq = priv->if_khz * 1000;
-       return 0;
-}
-
-static int xc5000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
-{
-       struct xc5000_priv *priv = fe->tuner_priv;
-       dprintk(1, "%s()\n", __func__);
-
-       *bw = priv->bandwidth;
-       return 0;
-}
-
-static int xc5000_get_status(struct dvb_frontend *fe, u32 *status)
-{
-       struct xc5000_priv *priv = fe->tuner_priv;
-       u16 lock_status = 0;
-
-       xc_get_lock_status(priv, &lock_status);
-
-       dprintk(1, "%s() lock_status = 0x%08x\n", __func__, lock_status);
-
-       *status = lock_status;
-
-       return 0;
-}
-
-static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
-{
-       struct xc5000_priv *priv = fe->tuner_priv;
-       int ret = XC_RESULT_SUCCESS;
-       u16 pll_lock_status;
-       u16 fw_ck;
-
-       if (force || xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
-
-fw_retry:
-
-               ret = xc5000_fwupload(fe);
-               if (ret != XC_RESULT_SUCCESS)
-                       return ret;
-
-               msleep(20);
-
-               if (priv->fw_checksum_supported) {
-                       if (xc5000_readreg(priv, XREG_FW_CHECKSUM, &fw_ck)
-                           != XC_RESULT_SUCCESS) {
-                               dprintk(1, "%s() FW checksum reading failed.\n",
-                                       __func__);
-                               goto fw_retry;
-                       }
-
-                       if (fw_ck == 0) {
-                               dprintk(1, "%s() FW checksum failed = 0x%04x\n",
-                                       __func__, fw_ck);
-                               goto fw_retry;
-                       }
-               }
-
-               /* Start the tuner self-calibration process */
-               ret |= xc_initialize(priv);
-
-               if (ret != XC_RESULT_SUCCESS)
-                       goto fw_retry;
-
-               /* Wait for calibration to complete.
-                * We could continue but XC5000 will clock stretch subsequent
-                * I2C transactions until calibration is complete.  This way we
-                * don't have to rely on clock stretching working.
-                */
-               xc_wait(100);
-
-               if (priv->init_status_supported) {
-                       if (xc5000_readreg(priv, XREG_INIT_STATUS, &fw_ck) != XC_RESULT_SUCCESS) {
-                               dprintk(1, "%s() FW failed reading init status.\n",
-                                       __func__);
-                               goto fw_retry;
-                       }
-
-                       if (fw_ck == 0) {
-                               dprintk(1, "%s() FW init status failed = 0x%04x\n", __func__, fw_ck);
-                               goto fw_retry;
-                       }
-               }
-
-               if (priv->pll_register_no) {
-                       xc5000_readreg(priv, priv->pll_register_no,
-                                      &pll_lock_status);
-                       if (pll_lock_status > 63) {
-                               /* PLL is unlocked, force reload of the firmware */
-                               printk(KERN_ERR "xc5000: PLL not running after fwload.\n");
-                               goto fw_retry;
-                       }
-               }
-
-               /* Default to "CABLE" mode */
-               ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
-       }
-
-       return ret;
-}
-
-static int xc5000_sleep(struct dvb_frontend *fe)
-{
-       int ret;
-
-       dprintk(1, "%s()\n", __func__);
-
-       /* Avoid firmware reload on slow devices */
-       if (no_poweroff)
-               return 0;
-
-       /* According to Xceive technical support, the "powerdown" register
-          was removed in newer versions of the firmware.  The "supported"
-          way to sleep the tuner is to pull the reset pin low for 10ms */
-       ret = xc5000_TunerReset(fe);
-       if (ret != XC_RESULT_SUCCESS) {
-               printk(KERN_ERR
-                       "xc5000: %s() unable to shutdown tuner\n",
-                       __func__);
-               return -EREMOTEIO;
-       } else
-               return XC_RESULT_SUCCESS;
-}
-
-static int xc5000_init(struct dvb_frontend *fe)
-{
-       struct xc5000_priv *priv = fe->tuner_priv;
-       dprintk(1, "%s()\n", __func__);
-
-       if (xc_load_fw_and_init_tuner(fe, 0) != XC_RESULT_SUCCESS) {
-               printk(KERN_ERR "xc5000: Unable to initialise tuner\n");
-               return -EREMOTEIO;
-       }
-
-       if (debug)
-               xc_debug_dump(priv);
-
-       return 0;
-}
-
-static int xc5000_release(struct dvb_frontend *fe)
-{
-       struct xc5000_priv *priv = fe->tuner_priv;
-
-       dprintk(1, "%s()\n", __func__);
-
-       mutex_lock(&xc5000_list_mutex);
-
-       if (priv)
-               hybrid_tuner_release_state(priv);
-
-       mutex_unlock(&xc5000_list_mutex);
-
-       fe->tuner_priv = NULL;
-
-       return 0;
-}
-
-static int xc5000_set_config(struct dvb_frontend *fe, void *priv_cfg)
-{
-       struct xc5000_priv *priv = fe->tuner_priv;
-       struct xc5000_config *p = priv_cfg;
-
-       dprintk(1, "%s()\n", __func__);
-
-       if (p->if_khz)
-               priv->if_khz = p->if_khz;
-
-       if (p->radio_input)
-               priv->radio_input = p->radio_input;
-
-       return 0;
-}
-
-
-static const struct dvb_tuner_ops xc5000_tuner_ops = {
-       .info = {
-               .name           = "Xceive XC5000",
-               .frequency_min  =    1000000,
-               .frequency_max  = 1023000000,
-               .frequency_step =      50000,
-       },
-
-       .release           = xc5000_release,
-       .init              = xc5000_init,
-       .sleep             = xc5000_sleep,
-
-       .set_config        = xc5000_set_config,
-       .set_params        = xc5000_set_params,
-       .set_analog_params = xc5000_set_analog_params,
-       .get_frequency     = xc5000_get_frequency,
-       .get_if_frequency  = xc5000_get_if_frequency,
-       .get_bandwidth     = xc5000_get_bandwidth,
-       .get_status        = xc5000_get_status
-};
-
-struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
-                                  struct i2c_adapter *i2c,
-                                  const struct xc5000_config *cfg)
-{
-       struct xc5000_priv *priv = NULL;
-       int instance;
-       u16 id = 0;
-
-       dprintk(1, "%s(%d-%04x)\n", __func__,
-               i2c ? i2c_adapter_id(i2c) : -1,
-               cfg ? cfg->i2c_address : -1);
-
-       mutex_lock(&xc5000_list_mutex);
-
-       instance = hybrid_tuner_request_state(struct xc5000_priv, priv,
-                                             hybrid_tuner_instance_list,
-                                             i2c, cfg->i2c_address, "xc5000");
-       switch (instance) {
-       case 0:
-               goto fail;
-               break;
-       case 1:
-               /* new tuner instance */
-               priv->bandwidth = 6000000;
-               fe->tuner_priv = priv;
-               break;
-       default:
-               /* existing tuner instance */
-               fe->tuner_priv = priv;
-               break;
-       }
-
-       if (priv->if_khz == 0) {
-               /* If the IF hasn't been set yet, use the value provided by
-                  the caller (occurs in hybrid devices where the analog
-                  call to xc5000_attach occurs before the digital side) */
-               priv->if_khz = cfg->if_khz;
-       }
-
-       if (priv->xtal_khz == 0)
-               priv->xtal_khz = cfg->xtal_khz;
-
-       if (priv->radio_input == 0)
-               priv->radio_input = cfg->radio_input;
-
-       /* don't override chip id if it's already been set
-          unless explicitly specified */
-       if ((priv->chip_id == 0) || (cfg->chip_id))
-               /* use default chip id if none specified, set to 0 so
-                  it can be overridden if this is a hybrid driver */
-               priv->chip_id = (cfg->chip_id) ? cfg->chip_id : 0;
-
-       /* Check if firmware has been loaded. It is possible that another
-          instance of the driver has loaded the firmware.
-        */
-       if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != XC_RESULT_SUCCESS)
-               goto fail;
-
-       switch (id) {
-       case XC_PRODUCT_ID_FW_LOADED:
-               printk(KERN_INFO
-                       "xc5000: Successfully identified at address 0x%02x\n",
-                       cfg->i2c_address);
-               printk(KERN_INFO
-                       "xc5000: Firmware has been loaded previously\n");
-               break;
-       case XC_PRODUCT_ID_FW_NOT_LOADED:
-               printk(KERN_INFO
-                       "xc5000: Successfully identified at address 0x%02x\n",
-                       cfg->i2c_address);
-               printk(KERN_INFO
-                       "xc5000: Firmware has not been loaded previously\n");
-               break;
-       default:
-               printk(KERN_ERR
-                       "xc5000: Device not found at addr 0x%02x (0x%x)\n",
-                       cfg->i2c_address, id);
-               goto fail;
-       }
-
-       mutex_unlock(&xc5000_list_mutex);
-
-       memcpy(&fe->ops.tuner_ops, &xc5000_tuner_ops,
-               sizeof(struct dvb_tuner_ops));
-
-       return fe;
-fail:
-       mutex_unlock(&xc5000_list_mutex);
-
-       xc5000_release(fe);
-       return NULL;
-}
-EXPORT_SYMBOL(xc5000_attach);
-
-MODULE_AUTHOR("Steven Toth");
-MODULE_DESCRIPTION("Xceive xc5000 silicon tuner driver");
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(XC5000A_FIRMWARE);
-MODULE_FIRMWARE(XC5000C_FIRMWARE);
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h
deleted file mode 100644 (file)
index b1a5474..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *  Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
- *
- *  Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
- *
- *  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 __XC5000_H__
-#define __XC5000_H__
-
-#include <linux/firmware.h>
-
-struct dvb_frontend;
-struct i2c_adapter;
-
-#define XC5000A 1
-#define XC5000C 2
-
-struct xc5000_config {
-       u8   i2c_address;
-       u32  if_khz;
-       u8   radio_input;
-       u16  xtal_khz;
-
-       int chip_id;
-};
-
-/* xc5000 callback command */
-#define XC5000_TUNER_RESET             0
-
-/* Possible Radio inputs */
-#define XC5000_RADIO_NOT_CONFIGURED            0
-#define XC5000_RADIO_FM1                       1
-#define XC5000_RADIO_FM2                       2
-#define XC5000_RADIO_FM1_MONO                  3
-
-/* 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) || \
-    (defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE))
-extern struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
-                                         struct i2c_adapter *i2c,
-                                         const struct xc5000_config *cfg);
-#else
-static inline struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
-                                                struct i2c_adapter *i2c,
-                                                const struct xc5000_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif
-
-#endif
index a378c529376495842f4f14c9f9e23f61c18332ed..208bc496b90aefa38083c975b57ddd9f2ddff3fb 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 ccflags-y += -I$(srctree)/drivers/media/dvb-core/
-ccflags-y += -I$(srctree)/drivers/media/common/tuners/
+ccflags-y += -I$(srctree)/drivers/media/tuners/
 
 stb0899-objs = stb0899_drv.o stb0899_algo.o
 stv0900-objs = stv0900_core.o stv0900_sw.o
index 36591ae505f48ec9896f803ac4302fe0e01dcfe0..c008d0c135d6a174975520175e07e83716bd8832 100644 (file)
@@ -3,4 +3,4 @@ obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o
 ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
 ccflags-y += -Idrivers/media/video/bt8xx
-ccflags-y += -Idrivers/media/common/tuners
+ccflags-y += -Idrivers/media/tuners
index 9d083c98ce587c701d1d20c16a0ca17818b746b8..7446c8b677b5c393a30edabdab8c55930b872b9c 100644 (file)
@@ -8,7 +8,7 @@ obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
 
 ccflags-y += -Idrivers/media/dvb-core/
 ccflags-y += -Idrivers/media/dvb-frontends/
-ccflags-y += -Idrivers/media/common/tuners/
+ccflags-y += -Idrivers/media/tuners/
 
 # For the staging CI driver cxd2099
 ccflags-y += -Idrivers/staging/media/cxd2099/
index 63997089f9d1f09d03f194149f221b25ba1bf700..5c0b5d6b9d69b773f93b9d133f874ef75143fcb7 100644 (file)
@@ -8,7 +8,7 @@ obj-$(CONFIG_DVB_NGENE) += ngene.o
 
 ccflags-y += -Idrivers/media/dvb-core/
 ccflags-y += -Idrivers/media/dvb-frontends/
-ccflags-y += -Idrivers/media/common/tuners/
+ccflags-y += -Idrivers/media/tuners/
 
 # For the staging CI driver cxd2099
 ccflags-y += -Idrivers/staging/media/cxd2099/
index 22a235f3cc48264524d481edb5938e16306258d2..98905963ff085c0b0e265b7bf26ae0d892aa6a83 100644 (file)
@@ -18,4 +18,4 @@ obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-patch.o
 obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o
 
 ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
-ccflags-y += -Idrivers/media/common/tuners
+ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig
new file mode 100644 (file)
index 0000000..94c6ff7
--- /dev/null
@@ -0,0 +1,243 @@
+config MEDIA_ATTACH
+       bool "Load and attach frontend and tuner driver modules as needed"
+       depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT
+       depends on MODULES
+       default y if !EXPERT
+       help
+         Remove the static dependency of DVB card drivers on all
+         frontend modules for all possible card variants. Instead,
+         allow the card drivers to only load the frontend modules
+         they require.
+
+         Also, tuner module will automatically load a tuner driver
+         when needed, for analog mode.
+
+         This saves several KBytes of memory.
+
+         Note: You will need module-init-tools v3.2 or later for this feature.
+
+         If unsure say Y.
+
+config MEDIA_TUNER
+       tristate
+       depends on (MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT) && I2C
+       default y
+       select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_XC4000 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMISE && MEDIA_RADIO_SUPPORT && EXPERIMENTAL
+       select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMISE && MEDIA_RADIO_SUPPORT
+       select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMISE
+       select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
+
+config MEDIA_TUNER_CUSTOMISE
+       bool "Customize analog and hybrid tuner modules to build"
+       depends on MEDIA_TUNER
+       default y if EXPERT
+       help
+         This allows the user to deselect tuner drivers unnecessary
+         for their hardware from the build. Use this option with care
+         as deselecting tuner drivers which are in fact necessary will
+         result in V4L/DVB devices which cannot be tuned due to lack of
+         driver support
+
+         If unsure say N.
+
+menu "Customize TV tuners"
+       visible if MEDIA_TUNER_CUSTOMISE
+       depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT
+
+config MEDIA_TUNER_SIMPLE
+       tristate "Simple tuner support"
+       depends on MEDIA_SUPPORT && I2C
+       select MEDIA_TUNER_TDA9887
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to include support for various simple tuners.
+
+config MEDIA_TUNER_TDA8290
+       tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo"
+       depends on MEDIA_SUPPORT && I2C
+       select MEDIA_TUNER_TDA827X
+       select MEDIA_TUNER_TDA18271
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to include support for Philips TDA8290+8275(a) tuner.
+
+config MEDIA_TUNER_TDA827X
+       tristate "Philips TDA827X silicon tuner"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         A DVB-T silicon tuner module. Say Y when you want to support this tuner.
+
+config MEDIA_TUNER_TDA18271
+       tristate "NXP TDA18271 silicon tuner"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         A silicon tuner module. Say Y when you want to support this tuner.
+
+config MEDIA_TUNER_TDA9887
+       tristate "TDA 9885/6/7 analog IF demodulator"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to include support for Philips TDA9885/6/7
+         analog IF demodulator.
+
+config MEDIA_TUNER_TEA5761
+       tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
+       depends on MEDIA_SUPPORT && I2C
+       depends on EXPERIMENTAL
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to include support for the Philips TEA5761 radio tuner.
+
+config MEDIA_TUNER_TEA5767
+       tristate "TEA 5767 radio tuner"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to include support for the Philips TEA5767 radio tuner.
+
+config MEDIA_TUNER_MT20XX
+       tristate "Microtune 2032 / 2050 tuners"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to include support for the MT2032 / MT2050 tuner.
+
+config MEDIA_TUNER_MT2060
+       tristate "Microtune MT2060 silicon IF tuner"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         A driver for the silicon IF tuner MT2060 from Microtune.
+
+config MEDIA_TUNER_MT2063
+       tristate "Microtune MT2063 silicon IF tuner"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         A driver for the silicon IF tuner MT2063 from Microtune.
+
+config MEDIA_TUNER_MT2266
+       tristate "Microtune MT2266 silicon tuner"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         A driver for the silicon baseband tuner MT2266 from Microtune.
+
+config MEDIA_TUNER_MT2131
+       tristate "Microtune MT2131 silicon tuner"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         A driver for the silicon baseband tuner MT2131 from Microtune.
+
+config MEDIA_TUNER_QT1010
+       tristate "Quantek QT1010 silicon tuner"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         A driver for the silicon tuner QT1010 from Quantek.
+
+config MEDIA_TUNER_XC2028
+       tristate "XCeive xc2028/xc3028 tuners"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to include support for the xc2028/xc3028 tuners.
+
+config MEDIA_TUNER_XC5000
+       tristate "Xceive XC5000 silicon tuner"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         A driver for the silicon tuner XC5000 from Xceive.
+         This device is only used inside a SiP called together with a
+         demodulator for now.
+
+config MEDIA_TUNER_XC4000
+       tristate "Xceive XC4000 silicon tuner"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         A driver for the silicon tuner XC4000 from Xceive.
+         This device is only used inside a SiP called together with a
+         demodulator for now.
+
+config MEDIA_TUNER_MXL5005S
+       tristate "MaxLinear MSL5005S silicon tuner"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         A driver for the silicon tuner MXL5005S from MaxLinear.
+
+config MEDIA_TUNER_MXL5007T
+       tristate "MaxLinear MxL5007T silicon tuner"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         A driver for the silicon tuner MxL5007T from MaxLinear.
+
+config MEDIA_TUNER_MC44S803
+       tristate "Freescale MC44S803 Low Power CMOS Broadband tuners"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         Say Y here to support the Freescale MC44S803 based tuners
+
+config MEDIA_TUNER_MAX2165
+       tristate "Maxim MAX2165 silicon tuner"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         A driver for the silicon tuner MAX2165 from Maxim.
+
+config MEDIA_TUNER_TDA18218
+       tristate "NXP TDA18218 silicon tuner"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         NXP TDA18218 silicon tuner driver.
+
+config MEDIA_TUNER_FC0011
+       tristate "Fitipower FC0011 silicon tuner"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         Fitipower FC0011 silicon tuner driver.
+
+config MEDIA_TUNER_FC0012
+       tristate "Fitipower FC0012 silicon tuner"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         Fitipower FC0012 silicon tuner driver.
+
+config MEDIA_TUNER_FC0013
+       tristate "Fitipower FC0013 silicon tuner"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         Fitipower FC0013 silicon tuner driver.
+
+config MEDIA_TUNER_TDA18212
+       tristate "NXP TDA18212 silicon tuner"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         NXP TDA18212 silicon tuner driver.
+
+config MEDIA_TUNER_TUA9001
+       tristate "Infineon TUA 9001 silicon tuner"
+       depends on MEDIA_SUPPORT && I2C
+       default m if MEDIA_TUNER_CUSTOMISE
+       help
+         Infineon TUA 9001 silicon tuner driver.
+endmenu
diff --git a/drivers/media/tuners/Makefile b/drivers/media/tuners/Makefile
new file mode 100644 (file)
index 0000000..112aeee
--- /dev/null
@@ -0,0 +1,37 @@
+#
+# Makefile for common V4L/DVB tuners
+#
+
+tda18271-objs := tda18271-maps.o tda18271-common.o tda18271-fe.o
+
+obj-$(CONFIG_MEDIA_TUNER_XC2028) += tuner-xc2028.o
+obj-$(CONFIG_MEDIA_TUNER_SIMPLE) += tuner-simple.o
+# tuner-types will be merged into tuner-simple, in the future
+obj-$(CONFIG_MEDIA_TUNER_SIMPLE) += tuner-types.o
+obj-$(CONFIG_MEDIA_TUNER_MT20XX) += mt20xx.o
+obj-$(CONFIG_MEDIA_TUNER_TDA8290) += tda8290.o
+obj-$(CONFIG_MEDIA_TUNER_TEA5767) += tea5767.o
+obj-$(CONFIG_MEDIA_TUNER_TEA5761) += tea5761.o
+obj-$(CONFIG_MEDIA_TUNER_TDA9887) += tda9887.o
+obj-$(CONFIG_MEDIA_TUNER_TDA827X) += tda827x.o
+obj-$(CONFIG_MEDIA_TUNER_TDA18271) += tda18271.o
+obj-$(CONFIG_MEDIA_TUNER_XC5000) += xc5000.o
+obj-$(CONFIG_MEDIA_TUNER_XC4000) += xc4000.o
+obj-$(CONFIG_MEDIA_TUNER_MT2060) += mt2060.o
+obj-$(CONFIG_MEDIA_TUNER_MT2063) += mt2063.o
+obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o
+obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
+obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
+obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
+obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
+obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
+obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
+obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o
+obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o
+obj-$(CONFIG_MEDIA_TUNER_TUA9001) += tua9001.o
+obj-$(CONFIG_MEDIA_TUNER_FC0011) += fc0011.o
+obj-$(CONFIG_MEDIA_TUNER_FC0012) += fc0012.o
+obj-$(CONFIG_MEDIA_TUNER_FC0013) += fc0013.o
+
+ccflags-y += -I$(srctree)/drivers/media/dvb-core
+ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
diff --git a/drivers/media/tuners/fc0011.c b/drivers/media/tuners/fc0011.c
new file mode 100644 (file)
index 0000000..e488254
--- /dev/null
@@ -0,0 +1,524 @@
+/*
+ * Fitipower FC0011 tuner driver
+ *
+ * Copyright (C) 2012 Michael Buesch <m@bues.ch>
+ *
+ * Derived from FC0012 tuner driver:
+ * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
+ *
+ * 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.
+ */
+
+#include "fc0011.h"
+
+
+/* Tuner registers */
+enum {
+       FC11_REG_0,
+       FC11_REG_FA,            /* FA */
+       FC11_REG_FP,            /* FP */
+       FC11_REG_XINHI,         /* XIN high 8 bit */
+       FC11_REG_XINLO,         /* XIN low 8 bit */
+       FC11_REG_VCO,           /* VCO */
+       FC11_REG_VCOSEL,        /* VCO select */
+       FC11_REG_7,             /* Unknown tuner reg 7 */
+       FC11_REG_8,             /* Unknown tuner reg 8 */
+       FC11_REG_9,
+       FC11_REG_10,            /* Unknown tuner reg 10 */
+       FC11_REG_11,            /* Unknown tuner reg 11 */
+       FC11_REG_12,
+       FC11_REG_RCCAL,         /* RC calibrate */
+       FC11_REG_VCOCAL,        /* VCO calibrate */
+       FC11_REG_15,
+       FC11_REG_16,            /* Unknown tuner reg 16 */
+       FC11_REG_17,
+
+       FC11_NR_REGS,           /* Number of registers */
+};
+
+enum FC11_REG_VCOSEL_bits {
+       FC11_VCOSEL_2           = 0x08, /* VCO select 2 */
+       FC11_VCOSEL_1           = 0x10, /* VCO select 1 */
+       FC11_VCOSEL_CLKOUT      = 0x20, /* Fix clock out */
+       FC11_VCOSEL_BW7M        = 0x40, /* 7MHz bw */
+       FC11_VCOSEL_BW6M        = 0x80, /* 6MHz bw */
+};
+
+enum FC11_REG_RCCAL_bits {
+       FC11_RCCAL_FORCE        = 0x10, /* force */
+};
+
+enum FC11_REG_VCOCAL_bits {
+       FC11_VCOCAL_RUN         = 0,    /* VCO calibration run */
+       FC11_VCOCAL_VALUEMASK   = 0x3F, /* VCO calibration value mask */
+       FC11_VCOCAL_OK          = 0x40, /* VCO calibration Ok */
+       FC11_VCOCAL_RESET       = 0x80, /* VCO calibration reset */
+};
+
+
+struct fc0011_priv {
+       struct i2c_adapter *i2c;
+       u8 addr;
+
+       u32 frequency;
+       u32 bandwidth;
+};
+
+
+static int fc0011_writereg(struct fc0011_priv *priv, u8 reg, u8 val)
+{
+       u8 buf[2] = { reg, val };
+       struct i2c_msg msg = { .addr = priv->addr,
+               .flags = 0, .buf = buf, .len = 2 };
+
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               dev_err(&priv->i2c->dev,
+                       "I2C write reg failed, reg: %02x, val: %02x\n",
+                       reg, val);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int fc0011_readreg(struct fc0011_priv *priv, u8 reg, u8 *val)
+{
+       u8 dummy;
+       struct i2c_msg msg[2] = {
+               { .addr = priv->addr,
+                 .flags = 0, .buf = &reg, .len = 1 },
+               { .addr = priv->addr,
+                 .flags = I2C_M_RD, .buf = val ? : &dummy, .len = 1 },
+       };
+
+       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
+               dev_err(&priv->i2c->dev,
+                       "I2C read failed, reg: %02x\n", reg);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int fc0011_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+
+       return 0;
+}
+
+static int fc0011_init(struct dvb_frontend *fe)
+{
+       struct fc0011_priv *priv = fe->tuner_priv;
+       int err;
+
+       if (WARN_ON(!fe->callback))
+               return -EINVAL;
+
+       err = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
+                          FC0011_FE_CALLBACK_POWER, priv->addr);
+       if (err) {
+               dev_err(&priv->i2c->dev, "Power-on callback failed\n");
+               return err;
+       }
+       err = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
+                          FC0011_FE_CALLBACK_RESET, priv->addr);
+       if (err) {
+               dev_err(&priv->i2c->dev, "Reset callback failed\n");
+               return err;
+       }
+
+       return 0;
+}
+
+/* Initiate VCO calibration */
+static int fc0011_vcocal_trigger(struct fc0011_priv *priv)
+{
+       int err;
+
+       err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RESET);
+       if (err)
+               return err;
+       err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RUN);
+       if (err)
+               return err;
+
+       return 0;
+}
+
+/* Read VCO calibration value */
+static int fc0011_vcocal_read(struct fc0011_priv *priv, u8 *value)
+{
+       int err;
+
+       err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RUN);
+       if (err)
+               return err;
+       usleep_range(10000, 20000);
+       err = fc0011_readreg(priv, FC11_REG_VCOCAL, value);
+       if (err)
+               return err;
+
+       return 0;
+}
+
+static int fc0011_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       struct fc0011_priv *priv = fe->tuner_priv;
+       int err;
+       unsigned int i, vco_retries;
+       u32 freq = p->frequency / 1000;
+       u32 bandwidth = p->bandwidth_hz / 1000;
+       u32 fvco, xin, xdiv, xdivr;
+       u16 frac;
+       u8 fa, fp, vco_sel, vco_cal;
+       u8 regs[FC11_NR_REGS] = { };
+
+       regs[FC11_REG_7] = 0x0F;
+       regs[FC11_REG_8] = 0x3E;
+       regs[FC11_REG_10] = 0xB8;
+       regs[FC11_REG_11] = 0x80;
+       regs[FC11_REG_RCCAL] = 0x04;
+       err = fc0011_writereg(priv, FC11_REG_7, regs[FC11_REG_7]);
+       err |= fc0011_writereg(priv, FC11_REG_8, regs[FC11_REG_8]);
+       err |= fc0011_writereg(priv, FC11_REG_10, regs[FC11_REG_10]);
+       err |= fc0011_writereg(priv, FC11_REG_11, regs[FC11_REG_11]);
+       err |= fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
+       if (err)
+               return -EIO;
+
+       /* Set VCO freq and VCO div */
+       if (freq < 54000) {
+               fvco = freq * 64;
+               regs[FC11_REG_VCO] = 0x82;
+       } else if (freq < 108000) {
+               fvco = freq * 32;
+               regs[FC11_REG_VCO] = 0x42;
+       } else if (freq < 216000) {
+               fvco = freq * 16;
+               regs[FC11_REG_VCO] = 0x22;
+       } else if (freq < 432000) {
+               fvco = freq * 8;
+               regs[FC11_REG_VCO] = 0x12;
+       } else {
+               fvco = freq * 4;
+               regs[FC11_REG_VCO] = 0x0A;
+       }
+
+       /* Calc XIN. The PLL reference frequency is 18 MHz. */
+       xdiv = fvco / 18000;
+       frac = fvco - xdiv * 18000;
+       frac = (frac << 15) / 18000;
+       if (frac >= 16384)
+               frac += 32786;
+       if (!frac)
+               xin = 0;
+       else if (frac < 511)
+               xin = 512;
+       else if (frac < 65026)
+               xin = frac;
+       else
+               xin = 65024;
+       regs[FC11_REG_XINHI] = xin >> 8;
+       regs[FC11_REG_XINLO] = xin;
+
+       /* Calc FP and FA */
+       xdivr = xdiv;
+       if (fvco - xdiv * 18000 >= 9000)
+               xdivr += 1; /* round */
+       fp = xdivr / 8;
+       fa = xdivr - fp * 8;
+       if (fa < 2) {
+               fp -= 1;
+               fa += 8;
+       }
+       if (fp > 0x1F) {
+               fp &= 0x1F;
+               fa &= 0xF;
+       }
+       if (fa >= fp) {
+               dev_warn(&priv->i2c->dev,
+                        "fa %02X >= fp %02X, but trying to continue\n",
+                        (unsigned int)(u8)fa, (unsigned int)(u8)fp);
+       }
+       regs[FC11_REG_FA] = fa;
+       regs[FC11_REG_FP] = fp;
+
+       /* Select bandwidth */
+       switch (bandwidth) {
+       case 8000:
+               break;
+       case 7000:
+               regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_BW7M;
+               break;
+       default:
+               dev_warn(&priv->i2c->dev, "Unsupported bandwidth %u kHz. "
+                        "Using 6000 kHz.\n",
+                        bandwidth);
+               bandwidth = 6000;
+               /* fallthrough */
+       case 6000:
+               regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_BW6M;
+               break;
+       }
+
+       /* Pre VCO select */
+       if (fvco < 2320000) {
+               vco_sel = 0;
+               regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+       } else if (fvco < 3080000) {
+               vco_sel = 1;
+               regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+               regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
+       } else {
+               vco_sel = 2;
+               regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+               regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
+       }
+
+       /* Fix for low freqs */
+       if (freq < 45000) {
+               regs[FC11_REG_FA] = 0x6;
+               regs[FC11_REG_FP] = 0x11;
+       }
+
+       /* Clock out fix */
+       regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_CLKOUT;
+
+       /* Write the cached registers */
+       for (i = FC11_REG_FA; i <= FC11_REG_VCOSEL; i++) {
+               err = fc0011_writereg(priv, i, regs[i]);
+               if (err)
+                       return err;
+       }
+
+       /* VCO calibration */
+       err = fc0011_vcocal_trigger(priv);
+       if (err)
+               return err;
+       err = fc0011_vcocal_read(priv, &vco_cal);
+       if (err)
+               return err;
+       vco_retries = 0;
+       while (!(vco_cal & FC11_VCOCAL_OK) && vco_retries < 3) {
+               /* Reset the tuner and try again */
+               err = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
+                                  FC0011_FE_CALLBACK_RESET, priv->addr);
+               if (err) {
+                       dev_err(&priv->i2c->dev, "Failed to reset tuner\n");
+                       return err;
+               }
+               /* Reinit tuner config */
+               err = 0;
+               for (i = FC11_REG_FA; i <= FC11_REG_VCOSEL; i++)
+                       err |= fc0011_writereg(priv, i, regs[i]);
+               err |= fc0011_writereg(priv, FC11_REG_7, regs[FC11_REG_7]);
+               err |= fc0011_writereg(priv, FC11_REG_8, regs[FC11_REG_8]);
+               err |= fc0011_writereg(priv, FC11_REG_10, regs[FC11_REG_10]);
+               err |= fc0011_writereg(priv, FC11_REG_11, regs[FC11_REG_11]);
+               err |= fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
+               if (err)
+                       return -EIO;
+               /* VCO calibration */
+               err = fc0011_vcocal_trigger(priv);
+               if (err)
+                       return err;
+               err = fc0011_vcocal_read(priv, &vco_cal);
+               if (err)
+                       return err;
+               vco_retries++;
+       }
+       if (!(vco_cal & FC11_VCOCAL_OK)) {
+               dev_err(&priv->i2c->dev,
+                       "Failed to read VCO calibration value (got %02X)\n",
+                       (unsigned int)vco_cal);
+               return -EIO;
+       }
+       vco_cal &= FC11_VCOCAL_VALUEMASK;
+
+       switch (vco_sel) {
+       case 0:
+               if (vco_cal < 8) {
+                       regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+                       regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
+                       err = fc0011_writereg(priv, FC11_REG_VCOSEL,
+                                             regs[FC11_REG_VCOSEL]);
+                       if (err)
+                               return err;
+                       err = fc0011_vcocal_trigger(priv);
+                       if (err)
+                               return err;
+               } else {
+                       regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+                       err = fc0011_writereg(priv, FC11_REG_VCOSEL,
+                                             regs[FC11_REG_VCOSEL]);
+                       if (err)
+                               return err;
+               }
+               break;
+       case 1:
+               if (vco_cal < 5) {
+                       regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+                       regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
+                       err = fc0011_writereg(priv, FC11_REG_VCOSEL,
+                                             regs[FC11_REG_VCOSEL]);
+                       if (err)
+                               return err;
+                       err = fc0011_vcocal_trigger(priv);
+                       if (err)
+                               return err;
+               } else if (vco_cal <= 48) {
+                       regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+                       regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
+                       err = fc0011_writereg(priv, FC11_REG_VCOSEL,
+                                             regs[FC11_REG_VCOSEL]);
+                       if (err)
+                               return err;
+               } else {
+                       regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+                       err = fc0011_writereg(priv, FC11_REG_VCOSEL,
+                                             regs[FC11_REG_VCOSEL]);
+                       if (err)
+                               return err;
+                       err = fc0011_vcocal_trigger(priv);
+                       if (err)
+                               return err;
+               }
+               break;
+       case 2:
+               if (vco_cal > 53) {
+                       regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+                       regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
+                       err = fc0011_writereg(priv, FC11_REG_VCOSEL,
+                                             regs[FC11_REG_VCOSEL]);
+                       if (err)
+                               return err;
+                       err = fc0011_vcocal_trigger(priv);
+                       if (err)
+                               return err;
+               } else {
+                       regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+                       regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
+                       err = fc0011_writereg(priv, FC11_REG_VCOSEL,
+                                             regs[FC11_REG_VCOSEL]);
+                       if (err)
+                               return err;
+               }
+               break;
+       }
+       err = fc0011_vcocal_read(priv, NULL);
+       if (err)
+               return err;
+       usleep_range(10000, 50000);
+
+       err = fc0011_readreg(priv, FC11_REG_RCCAL, &regs[FC11_REG_RCCAL]);
+       if (err)
+               return err;
+       regs[FC11_REG_RCCAL] |= FC11_RCCAL_FORCE;
+       err = fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
+       if (err)
+               return err;
+       err = fc0011_writereg(priv, FC11_REG_16, 0xB);
+       if (err)
+               return err;
+
+       dev_dbg(&priv->i2c->dev, "Tuned to "
+               "fa=%02X fp=%02X xin=%02X%02X vco=%02X vcosel=%02X "
+               "vcocal=%02X(%u) bw=%u\n",
+               (unsigned int)regs[FC11_REG_FA],
+               (unsigned int)regs[FC11_REG_FP],
+               (unsigned int)regs[FC11_REG_XINHI],
+               (unsigned int)regs[FC11_REG_XINLO],
+               (unsigned int)regs[FC11_REG_VCO],
+               (unsigned int)regs[FC11_REG_VCOSEL],
+               (unsigned int)vco_cal, vco_retries,
+               (unsigned int)bandwidth);
+
+       priv->frequency = p->frequency;
+       priv->bandwidth = p->bandwidth_hz;
+
+       return 0;
+}
+
+static int fc0011_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct fc0011_priv *priv = fe->tuner_priv;
+
+       *frequency = priv->frequency;
+
+       return 0;
+}
+
+static int fc0011_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       *frequency = 0;
+
+       return 0;
+}
+
+static int fc0011_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct fc0011_priv *priv = fe->tuner_priv;
+
+       *bandwidth = priv->bandwidth;
+
+       return 0;
+}
+
+static const struct dvb_tuner_ops fc0011_tuner_ops = {
+       .info = {
+               .name           = "Fitipower FC0011",
+
+               .frequency_min  = 45000000,
+               .frequency_max  = 1000000000,
+       },
+
+       .release                = fc0011_release,
+       .init                   = fc0011_init,
+
+       .set_params             = fc0011_set_params,
+
+       .get_frequency          = fc0011_get_frequency,
+       .get_if_frequency       = fc0011_get_if_frequency,
+       .get_bandwidth          = fc0011_get_bandwidth,
+};
+
+struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe,
+                                  struct i2c_adapter *i2c,
+                                  const struct fc0011_config *config)
+{
+       struct fc0011_priv *priv;
+
+       priv = kzalloc(sizeof(struct fc0011_priv), GFP_KERNEL);
+       if (!priv)
+               return NULL;
+
+       priv->i2c = i2c;
+       priv->addr = config->i2c_address;
+
+       fe->tuner_priv = priv;
+       fe->ops.tuner_ops = fc0011_tuner_ops;
+
+       dev_info(&priv->i2c->dev, "Fitipower FC0011 tuner attached\n");
+
+       return fe;
+}
+EXPORT_SYMBOL(fc0011_attach);
+
+MODULE_DESCRIPTION("Fitipower FC0011 silicon tuner driver");
+MODULE_AUTHOR("Michael Buesch <m@bues.ch>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/fc0011.h b/drivers/media/tuners/fc0011.h
new file mode 100644 (file)
index 0000000..0ee581f
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef LINUX_FC0011_H_
+#define LINUX_FC0011_H_
+
+#include "dvb_frontend.h"
+
+
+/** struct fc0011_config - fc0011 hardware config
+ *
+ * @i2c_address: I2C bus address.
+ */
+struct fc0011_config {
+       u8 i2c_address;
+};
+
+/** enum fc0011_fe_callback_commands - Frontend callbacks
+ *
+ * @FC0011_FE_CALLBACK_POWER: Power on tuner hardware.
+ * @FC0011_FE_CALLBACK_RESET: Request a tuner reset.
+ */
+enum fc0011_fe_callback_commands {
+       FC0011_FE_CALLBACK_POWER,
+       FC0011_FE_CALLBACK_RESET,
+};
+
+#if defined(CONFIG_MEDIA_TUNER_FC0011) ||\
+    defined(CONFIG_MEDIA_TUNER_FC0011_MODULE)
+struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe,
+                                  struct i2c_adapter *i2c,
+                                  const struct fc0011_config *config);
+#else
+static inline
+struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe,
+                                  struct i2c_adapter *i2c,
+                                  const struct fc0011_config *config)
+{
+       dev_err(&i2c->dev, "fc0011 driver disabled in Kconfig\n");
+       return NULL;
+}
+#endif
+
+#endif /* LINUX_FC0011_H_ */
diff --git a/drivers/media/tuners/fc0012-priv.h b/drivers/media/tuners/fc0012-priv.h
new file mode 100644 (file)
index 0000000..4577c91
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Fitipower FC0012 tuner driver - private includes
+ *
+ * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
+ *
+ * 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 _FC0012_PRIV_H_
+#define _FC0012_PRIV_H_
+
+#define LOG_PREFIX "fc0012"
+
+#undef err
+#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
+#undef info
+#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
+#undef warn
+#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
+
+struct fc0012_priv {
+       struct i2c_adapter *i2c;
+       u8 addr;
+       u8 dual_master;
+       u8 xtal_freq;
+
+       u32 frequency;
+       u32 bandwidth;
+};
+
+#endif
diff --git a/drivers/media/tuners/fc0012.c b/drivers/media/tuners/fc0012.c
new file mode 100644 (file)
index 0000000..308135a
--- /dev/null
@@ -0,0 +1,467 @@
+/*
+ * Fitipower FC0012 tuner driver
+ *
+ * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
+ *
+ * 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.
+ */
+
+#include "fc0012.h"
+#include "fc0012-priv.h"
+
+static int fc0012_writereg(struct fc0012_priv *priv, u8 reg, u8 val)
+{
+       u8 buf[2] = {reg, val};
+       struct i2c_msg msg = {
+               .addr = priv->addr, .flags = 0, .buf = buf, .len = 2
+       };
+
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               err("I2C write reg failed, reg: %02x, val: %02x", reg, val);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int fc0012_readreg(struct fc0012_priv *priv, u8 reg, u8 *val)
+{
+       struct i2c_msg msg[2] = {
+               { .addr = priv->addr, .flags = 0, .buf = &reg, .len = 1 },
+               { .addr = priv->addr, .flags = I2C_M_RD, .buf = val, .len = 1 },
+       };
+
+       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
+               err("I2C read reg failed, reg: %02x", reg);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int fc0012_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static int fc0012_init(struct dvb_frontend *fe)
+{
+       struct fc0012_priv *priv = fe->tuner_priv;
+       int i, ret = 0;
+       unsigned char reg[] = {
+               0x00,   /* dummy reg. 0 */
+               0x05,   /* reg. 0x01 */
+               0x10,   /* reg. 0x02 */
+               0x00,   /* reg. 0x03 */
+               0x00,   /* reg. 0x04 */
+               0x0f,   /* reg. 0x05: may also be 0x0a */
+               0x00,   /* reg. 0x06: divider 2, VCO slow */
+               0x00,   /* reg. 0x07: may also be 0x0f */
+               0xff,   /* reg. 0x08: AGC Clock divide by 256, AGC gain 1/256,
+                          Loop Bw 1/8 */
+               0x6e,   /* reg. 0x09: Disable LoopThrough, Enable LoopThrough: 0x6f */
+               0xb8,   /* reg. 0x0a: Disable LO Test Buffer */
+               0x82,   /* reg. 0x0b: Output Clock is same as clock frequency,
+                          may also be 0x83 */
+               0xfc,   /* reg. 0x0c: depending on AGC Up-Down mode, may need 0xf8 */
+               0x02,   /* reg. 0x0d: AGC Not Forcing & LNA Forcing, 0x02 for DVB-T */
+               0x00,   /* reg. 0x0e */
+               0x00,   /* reg. 0x0f */
+               0x00,   /* reg. 0x10: may also be 0x0d */
+               0x00,   /* reg. 0x11 */
+               0x1f,   /* reg. 0x12: Set to maximum gain */
+               0x08,   /* reg. 0x13: Set to Middle Gain: 0x08,
+                          Low Gain: 0x00, High Gain: 0x10, enable IX2: 0x80 */
+               0x00,   /* reg. 0x14 */
+               0x04,   /* reg. 0x15: Enable LNA COMPS */
+       };
+
+       switch (priv->xtal_freq) {
+       case FC_XTAL_27_MHZ:
+       case FC_XTAL_28_8_MHZ:
+               reg[0x07] |= 0x20;
+               break;
+       case FC_XTAL_36_MHZ:
+       default:
+               break;
+       }
+
+       if (priv->dual_master)
+               reg[0x0c] |= 0x02;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+       for (i = 1; i < sizeof(reg); i++) {
+               ret = fc0012_writereg(priv, i, reg[i]);
+               if (ret)
+                       break;
+       }
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+
+       if (ret)
+               err("fc0012_writereg failed: %d", ret);
+
+       return ret;
+}
+
+static int fc0012_sleep(struct dvb_frontend *fe)
+{
+       /* nothing to do here */
+       return 0;
+}
+
+static int fc0012_set_params(struct dvb_frontend *fe)
+{
+       struct fc0012_priv *priv = fe->tuner_priv;
+       int i, ret = 0;
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       u32 freq = p->frequency / 1000;
+       u32 delsys = p->delivery_system;
+       unsigned char reg[7], am, pm, multi, tmp;
+       unsigned long f_vco;
+       unsigned short xtal_freq_khz_2, xin, xdiv;
+       int vco_select = false;
+
+       if (fe->callback) {
+               ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
+                       FC_FE_CALLBACK_VHF_ENABLE, (freq > 300000 ? 0 : 1));
+               if (ret)
+                       goto exit;
+       }
+
+       switch (priv->xtal_freq) {
+       case FC_XTAL_27_MHZ:
+               xtal_freq_khz_2 = 27000 / 2;
+               break;
+       case FC_XTAL_36_MHZ:
+               xtal_freq_khz_2 = 36000 / 2;
+               break;
+       case FC_XTAL_28_8_MHZ:
+       default:
+               xtal_freq_khz_2 = 28800 / 2;
+               break;
+       }
+
+       /* select frequency divider and the frequency of VCO */
+       if (freq < 37084) {             /* freq * 96 < 3560000 */
+               multi = 96;
+               reg[5] = 0x82;
+               reg[6] = 0x00;
+       } else if (freq < 55625) {      /* freq * 64 < 3560000 */
+               multi = 64;
+               reg[5] = 0x82;
+               reg[6] = 0x02;
+       } else if (freq < 74167) {      /* freq * 48 < 3560000 */
+               multi = 48;
+               reg[5] = 0x42;
+               reg[6] = 0x00;
+       } else if (freq < 111250) {     /* freq * 32 < 3560000 */
+               multi = 32;
+               reg[5] = 0x42;
+               reg[6] = 0x02;
+       } else if (freq < 148334) {     /* freq * 24 < 3560000 */
+               multi = 24;
+               reg[5] = 0x22;
+               reg[6] = 0x00;
+       } else if (freq < 222500) {     /* freq * 16 < 3560000 */
+               multi = 16;
+               reg[5] = 0x22;
+               reg[6] = 0x02;
+       } else if (freq < 296667) {     /* freq * 12 < 3560000 */
+               multi = 12;
+               reg[5] = 0x12;
+               reg[6] = 0x00;
+       } else if (freq < 445000) {     /* freq * 8 < 3560000 */
+               multi = 8;
+               reg[5] = 0x12;
+               reg[6] = 0x02;
+       } else if (freq < 593334) {     /* freq * 6 < 3560000 */
+               multi = 6;
+               reg[5] = 0x0a;
+               reg[6] = 0x00;
+       } else {
+               multi = 4;
+               reg[5] = 0x0a;
+               reg[6] = 0x02;
+       }
+
+       f_vco = freq * multi;
+
+       if (f_vco >= 3060000) {
+               reg[6] |= 0x08;
+               vco_select = true;
+       }
+
+       if (freq >= 45000) {
+               /* From divided value (XDIV) determined the FA and FP value */
+               xdiv = (unsigned short)(f_vco / xtal_freq_khz_2);
+               if ((f_vco - xdiv * xtal_freq_khz_2) >= (xtal_freq_khz_2 / 2))
+                       xdiv++;
+
+               pm = (unsigned char)(xdiv / 8);
+               am = (unsigned char)(xdiv - (8 * pm));
+
+               if (am < 2) {
+                       reg[1] = am + 8;
+                       reg[2] = pm - 1;
+               } else {
+                       reg[1] = am;
+                       reg[2] = pm;
+               }
+       } else {
+               /* fix for frequency less than 45 MHz */
+               reg[1] = 0x06;
+               reg[2] = 0x11;
+       }
+
+       /* fix clock out */
+       reg[6] |= 0x20;
+
+       /* From VCO frequency determines the XIN ( fractional part of Delta
+          Sigma PLL) and divided value (XDIV) */
+       xin = (unsigned short)(f_vco - (f_vco / xtal_freq_khz_2) * xtal_freq_khz_2);
+       xin = (xin << 15) / xtal_freq_khz_2;
+       if (xin >= 16384)
+               xin += 32768;
+
+       reg[3] = xin >> 8;      /* xin with 9 bit resolution */
+       reg[4] = xin & 0xff;
+
+       if (delsys == SYS_DVBT) {
+               reg[6] &= 0x3f; /* bits 6 and 7 describe the bandwidth */
+               switch (p->bandwidth_hz) {
+               case 6000000:
+                       reg[6] |= 0x80;
+                       break;
+               case 7000000:
+                       reg[6] |= 0x40;
+                       break;
+               case 8000000:
+               default:
+                       break;
+               }
+       } else {
+               err("%s: modulation type not supported!", __func__);
+               return -EINVAL;
+       }
+
+       /* modified for Realtek demod */
+       reg[5] |= 0x07;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+       for (i = 1; i <= 6; i++) {
+               ret = fc0012_writereg(priv, i, reg[i]);
+               if (ret)
+                       goto exit;
+       }
+
+       /* VCO Calibration */
+       ret = fc0012_writereg(priv, 0x0e, 0x80);
+       if (!ret)
+               ret = fc0012_writereg(priv, 0x0e, 0x00);
+
+       /* VCO Re-Calibration if needed */
+       if (!ret)
+               ret = fc0012_writereg(priv, 0x0e, 0x00);
+
+       if (!ret) {
+               msleep(10);
+               ret = fc0012_readreg(priv, 0x0e, &tmp);
+       }
+       if (ret)
+               goto exit;
+
+       /* vco selection */
+       tmp &= 0x3f;
+
+       if (vco_select) {
+               if (tmp > 0x3c) {
+                       reg[6] &= ~0x08;
+                       ret = fc0012_writereg(priv, 0x06, reg[6]);
+                       if (!ret)
+                               ret = fc0012_writereg(priv, 0x0e, 0x80);
+                       if (!ret)
+                               ret = fc0012_writereg(priv, 0x0e, 0x00);
+               }
+       } else {
+               if (tmp < 0x02) {
+                       reg[6] |= 0x08;
+                       ret = fc0012_writereg(priv, 0x06, reg[6]);
+                       if (!ret)
+                               ret = fc0012_writereg(priv, 0x0e, 0x80);
+                       if (!ret)
+                               ret = fc0012_writereg(priv, 0x0e, 0x00);
+               }
+       }
+
+       priv->frequency = p->frequency;
+       priv->bandwidth = p->bandwidth_hz;
+
+exit:
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+       if (ret)
+               warn("%s: failed: %d", __func__, ret);
+       return ret;
+}
+
+static int fc0012_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct fc0012_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static int fc0012_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       /* CHECK: always ? */
+       *frequency = 0;
+       return 0;
+}
+
+static int fc0012_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct fc0012_priv *priv = fe->tuner_priv;
+       *bandwidth = priv->bandwidth;
+       return 0;
+}
+
+#define INPUT_ADC_LEVEL        -8
+
+static int fc0012_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct fc0012_priv *priv = fe->tuner_priv;
+       int ret;
+       unsigned char tmp;
+       int int_temp, lna_gain, int_lna, tot_agc_gain, power;
+       const int fc0012_lna_gain_table[] = {
+               /* low gain */
+               -63, -58, -99, -73,
+               -63, -65, -54, -60,
+               /* middle gain */
+                71,  70,  68,  67,
+                65,  63,  61,  58,
+               /* high gain */
+               197, 191, 188, 186,
+               184, 182, 181, 179,
+       };
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+       ret = fc0012_writereg(priv, 0x12, 0x00);
+       if (ret)
+               goto err;
+
+       ret = fc0012_readreg(priv, 0x12, &tmp);
+       if (ret)
+               goto err;
+       int_temp = tmp;
+
+       ret = fc0012_readreg(priv, 0x13, &tmp);
+       if (ret)
+               goto err;
+       lna_gain = tmp & 0x1f;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+
+       if (lna_gain < ARRAY_SIZE(fc0012_lna_gain_table)) {
+               int_lna = fc0012_lna_gain_table[lna_gain];
+               tot_agc_gain = (abs((int_temp >> 5) - 7) - 2 +
+                               (int_temp & 0x1f)) * 2;
+               power = INPUT_ADC_LEVEL - tot_agc_gain - int_lna / 10;
+
+               if (power >= 45)
+                       *strength = 255;        /* 100% */
+               else if (power < -95)
+                       *strength = 0;
+               else
+                       *strength = (power + 95) * 255 / 140;
+
+               *strength |= *strength << 8;
+       } else {
+               ret = -1;
+       }
+
+       goto exit;
+
+err:
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+exit:
+       if (ret)
+               warn("%s: failed: %d", __func__, ret);
+       return ret;
+}
+
+static const struct dvb_tuner_ops fc0012_tuner_ops = {
+       .info = {
+               .name           = "Fitipower FC0012",
+
+               .frequency_min  = 37000000,     /* estimate */
+               .frequency_max  = 862000000,    /* estimate */
+               .frequency_step = 0,
+       },
+
+       .release        = fc0012_release,
+
+       .init           = fc0012_init,
+       .sleep          = fc0012_sleep,
+
+       .set_params     = fc0012_set_params,
+
+       .get_frequency  = fc0012_get_frequency,
+       .get_if_frequency = fc0012_get_if_frequency,
+       .get_bandwidth  = fc0012_get_bandwidth,
+
+       .get_rf_strength = fc0012_get_rf_strength,
+};
+
+struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe,
+       struct i2c_adapter *i2c, u8 i2c_address, int dual_master,
+       enum fc001x_xtal_freq xtal_freq)
+{
+       struct fc0012_priv *priv = NULL;
+
+       priv = kzalloc(sizeof(struct fc0012_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->i2c = i2c;
+       priv->dual_master = dual_master;
+       priv->addr = i2c_address;
+       priv->xtal_freq = xtal_freq;
+
+       info("Fitipower FC0012 successfully attached.");
+
+       fe->tuner_priv = priv;
+
+       memcpy(&fe->ops.tuner_ops, &fc0012_tuner_ops,
+               sizeof(struct dvb_tuner_ops));
+
+       return fe;
+}
+EXPORT_SYMBOL(fc0012_attach);
+
+MODULE_DESCRIPTION("Fitipower FC0012 silicon tuner driver");
+MODULE_AUTHOR("Hans-Frieder Vogt <hfvogt@gmx.net>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.6");
diff --git a/drivers/media/tuners/fc0012.h b/drivers/media/tuners/fc0012.h
new file mode 100644 (file)
index 0000000..4dbd5ef
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Fitipower FC0012 tuner driver - include
+ *
+ * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
+ *
+ * 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 _FC0012_H_
+#define _FC0012_H_
+
+#include "dvb_frontend.h"
+#include "fc001x-common.h"
+
+#if defined(CONFIG_MEDIA_TUNER_FC0012) || \
+       (defined(CONFIG_MEDIA_TUNER_FC0012_MODULE) && defined(MODULE))
+extern struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe,
+                                       struct i2c_adapter *i2c,
+                                       u8 i2c_address, int dual_master,
+                                       enum fc001x_xtal_freq xtal_freq);
+#else
+static inline struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe,
+                                       struct i2c_adapter *i2c,
+                                       u8 i2c_address, int dual_master,
+                                       enum fc001x_xtal_freq xtal_freq)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/tuners/fc0013-priv.h b/drivers/media/tuners/fc0013-priv.h
new file mode 100644 (file)
index 0000000..bfd49de
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Fitipower FC0013 tuner driver
+ *
+ * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
+ *
+ *    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 _FC0013_PRIV_H_
+#define _FC0013_PRIV_H_
+
+#define LOG_PREFIX "fc0013"
+
+#undef err
+#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
+#undef info
+#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
+#undef warn
+#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
+
+struct fc0013_priv {
+       struct i2c_adapter *i2c;
+       u8 addr;
+       u8 dual_master;
+       u8 xtal_freq;
+
+       u32 frequency;
+       u32 bandwidth;
+};
+
+#endif
diff --git a/drivers/media/tuners/fc0013.c b/drivers/media/tuners/fc0013.c
new file mode 100644 (file)
index 0000000..bd8f0f1
--- /dev/null
@@ -0,0 +1,634 @@
+/*
+ * Fitipower FC0013 tuner driver
+ *
+ * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
+ * partially based on driver code from Fitipower
+ * Copyright (C) 2010 Fitipower Integrated Technology Inc
+ *
+ *    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.
+ *
+ */
+
+#include "fc0013.h"
+#include "fc0013-priv.h"
+
+static int fc0013_writereg(struct fc0013_priv *priv, u8 reg, u8 val)
+{
+       u8 buf[2] = {reg, val};
+       struct i2c_msg msg = {
+               .addr = priv->addr, .flags = 0, .buf = buf, .len = 2
+       };
+
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               err("I2C write reg failed, reg: %02x, val: %02x", reg, val);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int fc0013_readreg(struct fc0013_priv *priv, u8 reg, u8 *val)
+{
+       struct i2c_msg msg[2] = {
+               { .addr = priv->addr, .flags = 0, .buf = &reg, .len = 1 },
+               { .addr = priv->addr, .flags = I2C_M_RD, .buf = val, .len = 1 },
+       };
+
+       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
+               err("I2C read reg failed, reg: %02x", reg);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int fc0013_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static int fc0013_init(struct dvb_frontend *fe)
+{
+       struct fc0013_priv *priv = fe->tuner_priv;
+       int i, ret = 0;
+       unsigned char reg[] = {
+               0x00,   /* reg. 0x00: dummy */
+               0x09,   /* reg. 0x01 */
+               0x16,   /* reg. 0x02 */
+               0x00,   /* reg. 0x03 */
+               0x00,   /* reg. 0x04 */
+               0x17,   /* reg. 0x05 */
+               0x02,   /* reg. 0x06 */
+               0x0a,   /* reg. 0x07: CHECK */
+               0xff,   /* reg. 0x08: AGC Clock divide by 256, AGC gain 1/256,
+                          Loop Bw 1/8 */
+               0x6f,   /* reg. 0x09: enable LoopThrough */
+               0xb8,   /* reg. 0x0a: Disable LO Test Buffer */
+               0x82,   /* reg. 0x0b: CHECK */
+               0xfc,   /* reg. 0x0c: depending on AGC Up-Down mode, may need 0xf8 */
+               0x01,   /* reg. 0x0d: AGC Not Forcing & LNA Forcing, may need 0x02 */
+               0x00,   /* reg. 0x0e */
+               0x00,   /* reg. 0x0f */
+               0x00,   /* reg. 0x10 */
+               0x00,   /* reg. 0x11 */
+               0x00,   /* reg. 0x12 */
+               0x00,   /* reg. 0x13 */
+               0x50,   /* reg. 0x14: DVB-t High Gain, UHF.
+                          Middle Gain: 0x48, Low Gain: 0x40 */
+               0x01,   /* reg. 0x15 */
+       };
+
+       switch (priv->xtal_freq) {
+       case FC_XTAL_27_MHZ:
+       case FC_XTAL_28_8_MHZ:
+               reg[0x07] |= 0x20;
+               break;
+       case FC_XTAL_36_MHZ:
+       default:
+               break;
+       }
+
+       if (priv->dual_master)
+               reg[0x0c] |= 0x02;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+       for (i = 1; i < sizeof(reg); i++) {
+               ret = fc0013_writereg(priv, i, reg[i]);
+               if (ret)
+                       break;
+       }
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+
+       if (ret)
+               err("fc0013_writereg failed: %d", ret);
+
+       return ret;
+}
+
+static int fc0013_sleep(struct dvb_frontend *fe)
+{
+       /* nothing to do here */
+       return 0;
+}
+
+int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val)
+{
+       struct fc0013_priv *priv = fe->tuner_priv;
+       int ret;
+       u8 rc_cal;
+       int val;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+       /* push rc_cal value, get rc_cal value */
+       ret = fc0013_writereg(priv, 0x10, 0x00);
+       if (ret)
+               goto error_out;
+
+       /* get rc_cal value */
+       ret = fc0013_readreg(priv, 0x10, &rc_cal);
+       if (ret)
+               goto error_out;
+
+       rc_cal &= 0x0f;
+
+       val = (int)rc_cal + rc_val;
+
+       /* forcing rc_cal */
+       ret = fc0013_writereg(priv, 0x0d, 0x11);
+       if (ret)
+               goto error_out;
+
+       /* modify rc_cal value */
+       if (val > 15)
+               ret = fc0013_writereg(priv, 0x10, 0x0f);
+       else if (val < 0)
+               ret = fc0013_writereg(priv, 0x10, 0x00);
+       else
+               ret = fc0013_writereg(priv, 0x10, (u8)val);
+
+error_out:
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+
+       return ret;
+}
+EXPORT_SYMBOL(fc0013_rc_cal_add);
+
+int fc0013_rc_cal_reset(struct dvb_frontend *fe)
+{
+       struct fc0013_priv *priv = fe->tuner_priv;
+       int ret;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+       ret = fc0013_writereg(priv, 0x0d, 0x01);
+       if (!ret)
+               ret = fc0013_writereg(priv, 0x10, 0x00);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+
+       return ret;
+}
+EXPORT_SYMBOL(fc0013_rc_cal_reset);
+
+static int fc0013_set_vhf_track(struct fc0013_priv *priv, u32 freq)
+{
+       int ret;
+       u8 tmp;
+
+       ret = fc0013_readreg(priv, 0x1d, &tmp);
+       if (ret)
+               goto error_out;
+       tmp &= 0xe3;
+       if (freq <= 177500) {           /* VHF Track: 7 */
+               ret = fc0013_writereg(priv, 0x1d, tmp | 0x1c);
+       } else if (freq <= 184500) {    /* VHF Track: 6 */
+               ret = fc0013_writereg(priv, 0x1d, tmp | 0x18);
+       } else if (freq <= 191500) {    /* VHF Track: 5 */
+               ret = fc0013_writereg(priv, 0x1d, tmp | 0x14);
+       } else if (freq <= 198500) {    /* VHF Track: 4 */
+               ret = fc0013_writereg(priv, 0x1d, tmp | 0x10);
+       } else if (freq <= 205500) {    /* VHF Track: 3 */
+               ret = fc0013_writereg(priv, 0x1d, tmp | 0x0c);
+       } else if (freq <= 219500) {    /* VHF Track: 2 */
+               ret = fc0013_writereg(priv, 0x1d, tmp | 0x08);
+       } else if (freq < 300000) {     /* VHF Track: 1 */
+               ret = fc0013_writereg(priv, 0x1d, tmp | 0x04);
+       } else {                        /* UHF and GPS */
+               ret = fc0013_writereg(priv, 0x1d, tmp | 0x1c);
+       }
+       if (ret)
+               goto error_out;
+error_out:
+       return ret;
+}
+
+static int fc0013_set_params(struct dvb_frontend *fe)
+{
+       struct fc0013_priv *priv = fe->tuner_priv;
+       int i, ret = 0;
+       struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+       u32 freq = p->frequency / 1000;
+       u32 delsys = p->delivery_system;
+       unsigned char reg[7], am, pm, multi, tmp;
+       unsigned long f_vco;
+       unsigned short xtal_freq_khz_2, xin, xdiv;
+       int vco_select = false;
+
+       if (fe->callback) {
+               ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
+                       FC_FE_CALLBACK_VHF_ENABLE, (freq > 300000 ? 0 : 1));
+               if (ret)
+                       goto exit;
+       }
+
+       switch (priv->xtal_freq) {
+       case FC_XTAL_27_MHZ:
+               xtal_freq_khz_2 = 27000 / 2;
+               break;
+       case FC_XTAL_36_MHZ:
+               xtal_freq_khz_2 = 36000 / 2;
+               break;
+       case FC_XTAL_28_8_MHZ:
+       default:
+               xtal_freq_khz_2 = 28800 / 2;
+               break;
+       }
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+       /* set VHF track */
+       ret = fc0013_set_vhf_track(priv, freq);
+       if (ret)
+               goto exit;
+
+       if (freq < 300000) {
+               /* enable VHF filter */
+               ret = fc0013_readreg(priv, 0x07, &tmp);
+               if (ret)
+                       goto exit;
+               ret = fc0013_writereg(priv, 0x07, tmp | 0x10);
+               if (ret)
+                       goto exit;
+
+               /* disable UHF & disable GPS */
+               ret = fc0013_readreg(priv, 0x14, &tmp);
+               if (ret)
+                       goto exit;
+               ret = fc0013_writereg(priv, 0x14, tmp & 0x1f);
+               if (ret)
+                       goto exit;
+       } else if (freq <= 862000) {
+               /* disable VHF filter */
+               ret = fc0013_readreg(priv, 0x07, &tmp);
+               if (ret)
+                       goto exit;
+               ret = fc0013_writereg(priv, 0x07, tmp & 0xef);
+               if (ret)
+                       goto exit;
+
+               /* enable UHF & disable GPS */
+               ret = fc0013_readreg(priv, 0x14, &tmp);
+               if (ret)
+                       goto exit;
+               ret = fc0013_writereg(priv, 0x14, (tmp & 0x1f) | 0x40);
+               if (ret)
+                       goto exit;
+       } else {
+               /* disable VHF filter */
+               ret = fc0013_readreg(priv, 0x07, &tmp);
+               if (ret)
+                       goto exit;
+               ret = fc0013_writereg(priv, 0x07, tmp & 0xef);
+               if (ret)
+                       goto exit;
+
+               /* disable UHF & enable GPS */
+               ret = fc0013_readreg(priv, 0x14, &tmp);
+               if (ret)
+                       goto exit;
+               ret = fc0013_writereg(priv, 0x14, (tmp & 0x1f) | 0x20);
+               if (ret)
+                       goto exit;
+       }
+
+       /* select frequency divider and the frequency of VCO */
+       if (freq < 37084) {             /* freq * 96 < 3560000 */
+               multi = 96;
+               reg[5] = 0x82;
+               reg[6] = 0x00;
+       } else if (freq < 55625) {      /* freq * 64 < 3560000 */
+               multi = 64;
+               reg[5] = 0x02;
+               reg[6] = 0x02;
+       } else if (freq < 74167) {      /* freq * 48 < 3560000 */
+               multi = 48;
+               reg[5] = 0x42;
+               reg[6] = 0x00;
+       } else if (freq < 111250) {     /* freq * 32 < 3560000 */
+               multi = 32;
+               reg[5] = 0x82;
+               reg[6] = 0x02;
+       } else if (freq < 148334) {     /* freq * 24 < 3560000 */
+               multi = 24;
+               reg[5] = 0x22;
+               reg[6] = 0x00;
+       } else if (freq < 222500) {     /* freq * 16 < 3560000 */
+               multi = 16;
+               reg[5] = 0x42;
+               reg[6] = 0x02;
+       } else if (freq < 296667) {     /* freq * 12 < 3560000 */
+               multi = 12;
+               reg[5] = 0x12;
+               reg[6] = 0x00;
+       } else if (freq < 445000) {     /* freq * 8 < 3560000 */
+               multi = 8;
+               reg[5] = 0x22;
+               reg[6] = 0x02;
+       } else if (freq < 593334) {     /* freq * 6 < 3560000 */
+               multi = 6;
+               reg[5] = 0x0a;
+               reg[6] = 0x00;
+       } else if (freq < 950000) {     /* freq * 4 < 3800000 */
+               multi = 4;
+               reg[5] = 0x12;
+               reg[6] = 0x02;
+       } else {
+               multi = 2;
+               reg[5] = 0x0a;
+               reg[6] = 0x02;
+       }
+
+       f_vco = freq * multi;
+
+       if (f_vco >= 3060000) {
+               reg[6] |= 0x08;
+               vco_select = true;
+       }
+
+       if (freq >= 45000) {
+               /* From divided value (XDIV) determined the FA and FP value */
+               xdiv = (unsigned short)(f_vco / xtal_freq_khz_2);
+               if ((f_vco - xdiv * xtal_freq_khz_2) >= (xtal_freq_khz_2 / 2))
+                       xdiv++;
+
+               pm = (unsigned char)(xdiv / 8);
+               am = (unsigned char)(xdiv - (8 * pm));
+
+               if (am < 2) {
+                       reg[1] = am + 8;
+                       reg[2] = pm - 1;
+               } else {
+                       reg[1] = am;
+                       reg[2] = pm;
+               }
+       } else {
+               /* fix for frequency less than 45 MHz */
+               reg[1] = 0x06;
+               reg[2] = 0x11;
+       }
+
+       /* fix clock out */
+       reg[6] |= 0x20;
+
+       /* From VCO frequency determines the XIN ( fractional part of Delta
+          Sigma PLL) and divided value (XDIV) */
+       xin = (unsigned short)(f_vco - (f_vco / xtal_freq_khz_2) * xtal_freq_khz_2);
+       xin = (xin << 15) / xtal_freq_khz_2;
+       if (xin >= 16384)
+               xin += 32768;
+
+       reg[3] = xin >> 8;
+       reg[4] = xin & 0xff;
+
+       if (delsys == SYS_DVBT) {
+               reg[6] &= 0x3f; /* bits 6 and 7 describe the bandwidth */
+               switch (p->bandwidth_hz) {
+               case 6000000:
+                       reg[6] |= 0x80;
+                       break;
+               case 7000000:
+                       reg[6] |= 0x40;
+                       break;
+               case 8000000:
+               default:
+                       break;
+               }
+       } else {
+               err("%s: modulation type not supported!", __func__);
+               return -EINVAL;
+       }
+
+       /* modified for Realtek demod */
+       reg[5] |= 0x07;
+
+       for (i = 1; i <= 6; i++) {
+               ret = fc0013_writereg(priv, i, reg[i]);
+               if (ret)
+                       goto exit;
+       }
+
+       ret = fc0013_readreg(priv, 0x11, &tmp);
+       if (ret)
+               goto exit;
+       if (multi == 64)
+               ret = fc0013_writereg(priv, 0x11, tmp | 0x04);
+       else
+               ret = fc0013_writereg(priv, 0x11, tmp & 0xfb);
+       if (ret)
+               goto exit;
+
+       /* VCO Calibration */
+       ret = fc0013_writereg(priv, 0x0e, 0x80);
+       if (!ret)
+               ret = fc0013_writereg(priv, 0x0e, 0x00);
+
+       /* VCO Re-Calibration if needed */
+       if (!ret)
+               ret = fc0013_writereg(priv, 0x0e, 0x00);
+
+       if (!ret) {
+               msleep(10);
+               ret = fc0013_readreg(priv, 0x0e, &tmp);
+       }
+       if (ret)
+               goto exit;
+
+       /* vco selection */
+       tmp &= 0x3f;
+
+       if (vco_select) {
+               if (tmp > 0x3c) {
+                       reg[6] &= ~0x08;
+                       ret = fc0013_writereg(priv, 0x06, reg[6]);
+                       if (!ret)
+                               ret = fc0013_writereg(priv, 0x0e, 0x80);
+                       if (!ret)
+                               ret = fc0013_writereg(priv, 0x0e, 0x00);
+               }
+       } else {
+               if (tmp < 0x02) {
+                       reg[6] |= 0x08;
+                       ret = fc0013_writereg(priv, 0x06, reg[6]);
+                       if (!ret)
+                               ret = fc0013_writereg(priv, 0x0e, 0x80);
+                       if (!ret)
+                               ret = fc0013_writereg(priv, 0x0e, 0x00);
+               }
+       }
+
+       priv->frequency = p->frequency;
+       priv->bandwidth = p->bandwidth_hz;
+
+exit:
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+       if (ret)
+               warn("%s: failed: %d", __func__, ret);
+       return ret;
+}
+
+static int fc0013_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct fc0013_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static int fc0013_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       /* always ? */
+       *frequency = 0;
+       return 0;
+}
+
+static int fc0013_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct fc0013_priv *priv = fe->tuner_priv;
+       *bandwidth = priv->bandwidth;
+       return 0;
+}
+
+#define INPUT_ADC_LEVEL        -8
+
+static int fc0013_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct fc0013_priv *priv = fe->tuner_priv;
+       int ret;
+       unsigned char tmp;
+       int int_temp, lna_gain, int_lna, tot_agc_gain, power;
+       const int fc0013_lna_gain_table[] = {
+               /* low gain */
+               -63, -58, -99, -73,
+               -63, -65, -54, -60,
+               /* middle gain */
+                71,  70,  68,  67,
+                65,  63,  61,  58,
+               /* high gain */
+               197, 191, 188, 186,
+               184, 182, 181, 179,
+       };
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+       ret = fc0013_writereg(priv, 0x13, 0x00);
+       if (ret)
+               goto err;
+
+       ret = fc0013_readreg(priv, 0x13, &tmp);
+       if (ret)
+               goto err;
+       int_temp = tmp;
+
+       ret = fc0013_readreg(priv, 0x14, &tmp);
+       if (ret)
+               goto err;
+       lna_gain = tmp & 0x1f;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+
+       if (lna_gain < ARRAY_SIZE(fc0013_lna_gain_table)) {
+               int_lna = fc0013_lna_gain_table[lna_gain];
+               tot_agc_gain = (abs((int_temp >> 5) - 7) - 2 +
+                               (int_temp & 0x1f)) * 2;
+               power = INPUT_ADC_LEVEL - tot_agc_gain - int_lna / 10;
+
+               if (power >= 45)
+                       *strength = 255;        /* 100% */
+               else if (power < -95)
+                       *strength = 0;
+               else
+                       *strength = (power + 95) * 255 / 140;
+
+               *strength |= *strength << 8;
+       } else {
+               ret = -1;
+       }
+
+       goto exit;
+
+err:
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+exit:
+       if (ret)
+               warn("%s: failed: %d", __func__, ret);
+       return ret;
+}
+
+static const struct dvb_tuner_ops fc0013_tuner_ops = {
+       .info = {
+               .name           = "Fitipower FC0013",
+
+               .frequency_min  = 37000000,     /* estimate */
+               .frequency_max  = 1680000000,   /* CHECK */
+               .frequency_step = 0,
+       },
+
+       .release        = fc0013_release,
+
+       .init           = fc0013_init,
+       .sleep          = fc0013_sleep,
+
+       .set_params     = fc0013_set_params,
+
+       .get_frequency  = fc0013_get_frequency,
+       .get_if_frequency = fc0013_get_if_frequency,
+       .get_bandwidth  = fc0013_get_bandwidth,
+
+       .get_rf_strength = fc0013_get_rf_strength,
+};
+
+struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe,
+       struct i2c_adapter *i2c, u8 i2c_address, int dual_master,
+       enum fc001x_xtal_freq xtal_freq)
+{
+       struct fc0013_priv *priv = NULL;
+
+       priv = kzalloc(sizeof(struct fc0013_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->i2c = i2c;
+       priv->dual_master = dual_master;
+       priv->addr = i2c_address;
+       priv->xtal_freq = xtal_freq;
+
+       info("Fitipower FC0013 successfully attached.");
+
+       fe->tuner_priv = priv;
+
+       memcpy(&fe->ops.tuner_ops, &fc0013_tuner_ops,
+               sizeof(struct dvb_tuner_ops));
+
+       return fe;
+}
+EXPORT_SYMBOL(fc0013_attach);
+
+MODULE_DESCRIPTION("Fitipower FC0013 silicon tuner driver");
+MODULE_AUTHOR("Hans-Frieder Vogt <hfvogt@gmx.net>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.2");
diff --git a/drivers/media/tuners/fc0013.h b/drivers/media/tuners/fc0013.h
new file mode 100644 (file)
index 0000000..594efd6
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Fitipower FC0013 tuner driver
+ *
+ * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
+ *
+ *    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 _FC0013_H_
+#define _FC0013_H_
+
+#include "dvb_frontend.h"
+#include "fc001x-common.h"
+
+#if defined(CONFIG_MEDIA_TUNER_FC0013) || \
+       (defined(CONFIG_MEDIA_TUNER_FC0013_MODULE) && defined(MODULE))
+extern struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe,
+                                       struct i2c_adapter *i2c,
+                                       u8 i2c_address, int dual_master,
+                                       enum fc001x_xtal_freq xtal_freq);
+extern int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val);
+extern int fc0013_rc_cal_reset(struct dvb_frontend *fe);
+#else
+static inline struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe,
+                                       struct i2c_adapter *i2c,
+                                       u8 i2c_address, int dual_master,
+                                       enum fc001x_xtal_freq xtal_freq)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+static inline int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val)
+{
+       return 0;
+}
+
+static inline int fc0013_rc_cal_reset(struct dvb_frontend *fe)
+{
+       return 0;
+}
+#endif
+
+#endif
diff --git a/drivers/media/tuners/fc001x-common.h b/drivers/media/tuners/fc001x-common.h
new file mode 100644 (file)
index 0000000..7188181
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Fitipower FC0012 & FC0013 tuner driver - common defines
+ *
+ * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
+ *
+ * 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 _FC001X_COMMON_H_
+#define _FC001X_COMMON_H_
+
+enum fc001x_xtal_freq {
+       FC_XTAL_27_MHZ,         /* 27000000 */
+       FC_XTAL_28_8_MHZ,       /* 28800000 */
+       FC_XTAL_36_MHZ,         /* 36000000 */
+};
+
+/*
+ * enum fc001x_fe_callback_commands - Frontend callbacks
+ *
+ * @FC_FE_CALLBACK_VHF_ENABLE: enable VHF or UHF
+ */
+enum fc001x_fe_callback_commands {
+       FC_FE_CALLBACK_VHF_ENABLE,
+};
+
+#endif
diff --git a/drivers/media/tuners/max2165.c b/drivers/media/tuners/max2165.c
new file mode 100644 (file)
index 0000000..ba84936
--- /dev/null
@@ -0,0 +1,433 @@
+/*
+ *  Driver for Maxim MAX2165 silicon tuner
+ *
+ *  Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/videodev2.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+
+#include "max2165.h"
+#include "max2165_priv.h"
+#include "tuner-i2c.h"
+
+#define dprintk(args...) \
+       do { \
+               if (debug) \
+                       printk(KERN_DEBUG "max2165: " args); \
+       } while (0)
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+static int max2165_write_reg(struct max2165_priv *priv, u8 reg, u8 data)
+{
+       int ret;
+       u8 buf[] = { reg, data };
+       struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
+
+       msg.addr = priv->config->i2c_address;
+
+       if (debug >= 2)
+               dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, data);
+
+       ret = i2c_transfer(priv->i2c, &msg, 1);
+
+       if (ret != 1)
+               dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
+                       __func__, reg, data, ret);
+
+       return (ret != 1) ? -EIO : 0;
+}
+
+static int max2165_read_reg(struct max2165_priv *priv, u8 reg, u8 *p_data)
+{
+       int ret;
+       u8 dev_addr = priv->config->i2c_address;
+
+       u8 b0[] = { reg };
+       u8 b1[] = { 0 };
+       struct i2c_msg msg[] = {
+               { .addr = dev_addr, .flags = 0, .buf = b0, .len = 1 },
+               { .addr = dev_addr, .flags = I2C_M_RD, .buf = b1, .len = 1 },
+       };
+
+       ret = i2c_transfer(priv->i2c, msg, 2);
+       if (ret != 2) {
+               dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret);
+               return -EIO;
+       }
+
+       *p_data = b1[0];
+       if (debug >= 2)
+               dprintk("%s: reg=0x%02X, data=0x%02X\n",
+                       __func__, reg, b1[0]);
+       return 0;
+}
+
+static int max2165_mask_write_reg(struct max2165_priv *priv, u8 reg,
+       u8 mask, u8 data)
+{
+       int ret;
+       u8 v;
+
+       data &= mask;
+       ret = max2165_read_reg(priv, reg, &v);
+       if (ret != 0)
+               return ret;
+       v &= ~mask;
+       v |= data;
+       ret = max2165_write_reg(priv, reg, v);
+
+       return ret;
+}
+
+static int max2165_read_rom_table(struct max2165_priv *priv)
+{
+       u8 dat[3];
+       int i;
+
+       for (i = 0; i < 3; i++) {
+               max2165_write_reg(priv, REG_ROM_TABLE_ADDR, i + 1);
+               max2165_read_reg(priv, REG_ROM_TABLE_DATA, &dat[i]);
+       }
+
+       priv->tf_ntch_low_cfg = dat[0] >> 4;
+       priv->tf_ntch_hi_cfg = dat[0] & 0x0F;
+       priv->tf_balun_low_ref = dat[1] & 0x0F;
+       priv->tf_balun_hi_ref = dat[1] >> 4;
+       priv->bb_filter_7mhz_cfg = dat[2] & 0x0F;
+       priv->bb_filter_8mhz_cfg = dat[2] >> 4;
+
+       dprintk("tf_ntch_low_cfg = 0x%X\n", priv->tf_ntch_low_cfg);
+       dprintk("tf_ntch_hi_cfg = 0x%X\n", priv->tf_ntch_hi_cfg);
+       dprintk("tf_balun_low_ref = 0x%X\n", priv->tf_balun_low_ref);
+       dprintk("tf_balun_hi_ref = 0x%X\n", priv->tf_balun_hi_ref);
+       dprintk("bb_filter_7mhz_cfg = 0x%X\n", priv->bb_filter_7mhz_cfg);
+       dprintk("bb_filter_8mhz_cfg = 0x%X\n", priv->bb_filter_8mhz_cfg);
+
+       return 0;
+}
+
+static int max2165_set_osc(struct max2165_priv *priv, u8 osc /*MHz*/)
+{
+       u8 v;
+
+       v = (osc / 2);
+       if (v == 2)
+               v = 0x7;
+       else
+               v -= 8;
+
+       max2165_mask_write_reg(priv, REG_PLL_CFG, 0x07, v);
+
+       return 0;
+}
+
+static int max2165_set_bandwidth(struct max2165_priv *priv, u32 bw)
+{
+       u8 val;
+
+       if (bw == 8000000)
+               val = priv->bb_filter_8mhz_cfg;
+       else
+               val = priv->bb_filter_7mhz_cfg;
+
+       max2165_mask_write_reg(priv, REG_BASEBAND_CTRL, 0xF0, val << 4);
+
+       return 0;
+}
+
+int fixpt_div32(u32 dividend, u32 divisor, u32 *quotient, u32 *fraction)
+{
+       u32 remainder;
+       u32 q, f = 0;
+       int i;
+
+       if (0 == divisor)
+               return -EINVAL;
+
+       q = dividend / divisor;
+       remainder = dividend - q * divisor;
+
+       for (i = 0; i < 31; i++) {
+               remainder <<= 1;
+               if (remainder >= divisor) {
+                       f += 1;
+                       remainder -= divisor;
+               }
+               f <<= 1;
+       }
+
+       *quotient = q;
+       *fraction = f;
+
+       return 0;
+}
+
+static int max2165_set_rf(struct max2165_priv *priv, u32 freq)
+{
+       u8 tf;
+       u8 tf_ntch;
+       u32 t;
+       u32 quotient, fraction;
+       int ret;
+
+       /* Set PLL divider according to RF frequency */
+       ret = fixpt_div32(freq / 1000, priv->config->osc_clk * 1000,
+                        &quotient, &fraction);
+       if (ret != 0)
+               return ret;
+
+       /* 20-bit fraction */
+       fraction >>= 12;
+
+       max2165_write_reg(priv, REG_NDIV_INT, quotient);
+       max2165_mask_write_reg(priv, REG_NDIV_FRAC2, 0x0F, fraction >> 16);
+       max2165_write_reg(priv, REG_NDIV_FRAC1, fraction >> 8);
+       max2165_write_reg(priv, REG_NDIV_FRAC0, fraction);
+
+       /* Norch Filter */
+       tf_ntch = (freq < 725000000) ?
+               priv->tf_ntch_low_cfg : priv->tf_ntch_hi_cfg;
+
+       /* Tracking filter balun */
+       t = priv->tf_balun_low_ref;
+       t += (priv->tf_balun_hi_ref - priv->tf_balun_low_ref)
+               * (freq / 1000 - 470000) / (780000 - 470000);
+
+       tf = t;
+       dprintk("tf = %X\n", tf);
+       tf |= tf_ntch << 4;
+
+       max2165_write_reg(priv, REG_TRACK_FILTER, tf);
+
+       return 0;
+}
+
+static void max2165_debug_status(struct max2165_priv *priv)
+{
+       u8 status, autotune;
+       u8 auto_vco_success, auto_vco_active;
+       u8 pll_locked;
+       u8 dc_offset_low, dc_offset_hi;
+       u8 signal_lv_over_threshold;
+       u8 vco, vco_sub_band, adc;
+
+       max2165_read_reg(priv, REG_STATUS, &status);
+       max2165_read_reg(priv, REG_AUTOTUNE, &autotune);
+
+       auto_vco_success = (status >> 6) & 0x01;
+       auto_vco_active = (status >> 5) & 0x01;
+       pll_locked = (status >> 4) & 0x01;
+       dc_offset_low = (status >> 3) & 0x01;
+       dc_offset_hi = (status >> 2) & 0x01;
+       signal_lv_over_threshold = status & 0x01;
+
+       vco = autotune >> 6;
+       vco_sub_band = (autotune >> 3) & 0x7;
+       adc = autotune & 0x7;
+
+       dprintk("auto VCO active: %d, auto VCO success: %d\n",
+               auto_vco_active, auto_vco_success);
+       dprintk("PLL locked: %d\n", pll_locked);
+       dprintk("DC offset low: %d, DC offset high: %d\n",
+               dc_offset_low, dc_offset_hi);
+       dprintk("Signal lvl over threshold: %d\n", signal_lv_over_threshold);
+       dprintk("VCO: %d, VCO Sub-band: %d, ADC: %d\n", vco, vco_sub_band, adc);
+}
+
+static int max2165_set_params(struct dvb_frontend *fe)
+{
+       struct max2165_priv *priv = fe->tuner_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret;
+
+       switch (c->bandwidth_hz) {
+       case 7000000:
+       case 8000000:
+               priv->frequency = c->frequency;
+               break;
+       default:
+               printk(KERN_INFO "MAX2165: bandwidth %d Hz not supported.\n",
+                      c->bandwidth_hz);
+               return -EINVAL;
+       }
+
+       dprintk("%s() frequency=%d\n", __func__, c->frequency);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       max2165_set_bandwidth(priv, c->bandwidth_hz);
+       ret = max2165_set_rf(priv, priv->frequency);
+       mdelay(50);
+       max2165_debug_status(priv);
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       if (ret != 0)
+               return -EREMOTEIO;
+
+       return 0;
+}
+
+static int max2165_get_frequency(struct dvb_frontend *fe, u32 *freq)
+{
+       struct max2165_priv *priv = fe->tuner_priv;
+       dprintk("%s()\n", __func__);
+       *freq = priv->frequency;
+       return 0;
+}
+
+static int max2165_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
+{
+       struct max2165_priv *priv = fe->tuner_priv;
+       dprintk("%s()\n", __func__);
+
+       *bw = priv->bandwidth;
+       return 0;
+}
+
+static int max2165_get_status(struct dvb_frontend *fe, u32 *status)
+{
+       struct max2165_priv *priv = fe->tuner_priv;
+       u16 lock_status = 0;
+
+       dprintk("%s()\n", __func__);
+
+       if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+
+       max2165_debug_status(priv);
+       *status = lock_status;
+
+       if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+
+       return 0;
+}
+
+static int max2165_sleep(struct dvb_frontend *fe)
+{
+       dprintk("%s()\n", __func__);
+       return 0;
+}
+
+static int max2165_init(struct dvb_frontend *fe)
+{
+       struct max2165_priv *priv = fe->tuner_priv;
+       dprintk("%s()\n", __func__);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       /* Setup initial values */
+       /* Fractional Mode on */
+       max2165_write_reg(priv, REG_NDIV_FRAC2, 0x18);
+       /* LNA on */
+       max2165_write_reg(priv, REG_LNA, 0x01);
+       max2165_write_reg(priv, REG_PLL_CFG, 0x7A);
+       max2165_write_reg(priv, REG_TEST, 0x08);
+       max2165_write_reg(priv, REG_SHUTDOWN, 0x40);
+       max2165_write_reg(priv, REG_VCO_CTRL, 0x84);
+       max2165_write_reg(priv, REG_BASEBAND_CTRL, 0xC3);
+       max2165_write_reg(priv, REG_DC_OFFSET_CTRL, 0x75);
+       max2165_write_reg(priv, REG_DC_OFFSET_DAC, 0x00);
+       max2165_write_reg(priv, REG_ROM_TABLE_ADDR, 0x00);
+
+       max2165_set_osc(priv, priv->config->osc_clk);
+
+       max2165_read_rom_table(priv);
+
+       max2165_set_bandwidth(priv, 8000000);
+
+       if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+
+       return 0;
+}
+
+static int max2165_release(struct dvb_frontend *fe)
+{
+       struct max2165_priv *priv = fe->tuner_priv;
+       dprintk("%s()\n", __func__);
+
+       kfree(priv);
+       fe->tuner_priv = NULL;
+
+       return 0;
+}
+
+static const struct dvb_tuner_ops max2165_tuner_ops = {
+       .info = {
+               .name           = "Maxim MAX2165",
+               .frequency_min  = 470000000,
+               .frequency_max  = 780000000,
+               .frequency_step =     50000,
+       },
+
+       .release           = max2165_release,
+       .init              = max2165_init,
+       .sleep             = max2165_sleep,
+
+       .set_params        = max2165_set_params,
+       .set_analog_params = NULL,
+       .get_frequency     = max2165_get_frequency,
+       .get_bandwidth     = max2165_get_bandwidth,
+       .get_status        = max2165_get_status
+};
+
+struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
+                                  struct i2c_adapter *i2c,
+                                  struct max2165_config *cfg)
+{
+       struct max2165_priv *priv = NULL;
+
+       dprintk("%s(%d-%04x)\n", __func__,
+               i2c ? i2c_adapter_id(i2c) : -1,
+               cfg ? cfg->i2c_address : -1);
+
+       priv = kzalloc(sizeof(struct max2165_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       memcpy(&fe->ops.tuner_ops, &max2165_tuner_ops,
+               sizeof(struct dvb_tuner_ops));
+
+       priv->config = cfg;
+       priv->i2c = i2c;
+       fe->tuner_priv = priv;
+
+       max2165_init(fe);
+       max2165_debug_status(priv);
+
+       return fe;
+}
+EXPORT_SYMBOL(max2165_attach);
+
+MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
+MODULE_DESCRIPTION("Maxim MAX2165 silicon tuner driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/max2165.h b/drivers/media/tuners/max2165.h
new file mode 100644 (file)
index 0000000..c063c36
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *  Driver for Maxim MAX2165 silicon tuner
+ *
+ *  Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MAX2165_H__
+#define __MAX2165_H__
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct max2165_config {
+       u8 i2c_address;
+       u8 osc_clk; /* in MHz, selectable values: 4,16,18,20,22,24,26,28 */
+};
+
+#if defined(CONFIG_MEDIA_TUNER_MAX2165) || \
+    (defined(CONFIG_MEDIA_TUNER_MAX2165_MODULE) && defined(MODULE))
+extern struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
+       struct i2c_adapter *i2c,
+       struct max2165_config *cfg);
+#else
+static inline struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
+       struct i2c_adapter *i2c,
+       struct max2165_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/tuners/max2165_priv.h b/drivers/media/tuners/max2165_priv.h
new file mode 100644 (file)
index 0000000..91bbe02
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *  Driver for Maxim MAX2165 silicon tuner
+ *
+ *  Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MAX2165_PRIV_H__
+#define __MAX2165_PRIV_H__
+
+#define REG_NDIV_INT 0x00
+#define REG_NDIV_FRAC2 0x01
+#define REG_NDIV_FRAC1 0x02
+#define REG_NDIV_FRAC0 0x03
+#define REG_TRACK_FILTER 0x04
+#define REG_LNA 0x05
+#define REG_PLL_CFG 0x06
+#define REG_TEST 0x07
+#define REG_SHUTDOWN 0x08
+#define REG_VCO_CTRL 0x09
+#define REG_BASEBAND_CTRL 0x0A
+#define REG_DC_OFFSET_CTRL 0x0B
+#define REG_DC_OFFSET_DAC 0x0C
+#define REG_ROM_TABLE_ADDR 0x0D
+
+/* Read Only Registers */
+#define REG_ROM_TABLE_DATA 0x10
+#define REG_STATUS 0x11
+#define REG_AUTOTUNE 0x12
+
+struct max2165_priv {
+       struct max2165_config *config;
+       struct i2c_adapter *i2c;
+
+       u32 frequency;
+       u32 bandwidth;
+
+       u8 tf_ntch_low_cfg;
+       u8 tf_ntch_hi_cfg;
+       u8 tf_balun_low_ref;
+       u8 tf_balun_hi_ref;
+       u8 bb_filter_7mhz_cfg;
+       u8 bb_filter_8mhz_cfg;
+};
+
+#endif
diff --git a/drivers/media/tuners/mc44s803.c b/drivers/media/tuners/mc44s803.c
new file mode 100644 (file)
index 0000000..5ddce7e
--- /dev/null
@@ -0,0 +1,372 @@
+/*
+ *  Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
+ *
+ *  Copyright (c) 2009 Jochen Friedrich <jochen@scram.de>
+ *
+ *  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.=
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+
+#include "mc44s803.h"
+#include "mc44s803_priv.h"
+
+#define mc_printk(level, format, arg...)       \
+       printk(level "mc44s803: " format , ## arg)
+
+/* Writes a single register */
+static int mc44s803_writereg(struct mc44s803_priv *priv, u32 val)
+{
+       u8 buf[3];
+       struct i2c_msg msg = {
+               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 3
+       };
+
+       buf[0] = (val & 0xff0000) >> 16;
+       buf[1] = (val & 0xff00) >> 8;
+       buf[2] = (val & 0xff);
+
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               mc_printk(KERN_WARNING, "I2C write failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+/* Reads a single register */
+static int mc44s803_readreg(struct mc44s803_priv *priv, u8 reg, u32 *val)
+{
+       u32 wval;
+       u8 buf[3];
+       int ret;
+       struct i2c_msg msg[] = {
+               { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
+                 .buf = buf, .len = 3 },
+       };
+
+       wval = MC44S803_REG_SM(MC44S803_REG_DATAREG, MC44S803_ADDR) |
+              MC44S803_REG_SM(reg, MC44S803_D);
+
+       ret = mc44s803_writereg(priv, wval);
+       if (ret)
+               return ret;
+
+       if (i2c_transfer(priv->i2c, msg, 1) != 1) {
+               mc_printk(KERN_WARNING, "I2C read failed\n");
+               return -EREMOTEIO;
+       }
+
+       *val = (buf[0] << 16) | (buf[1] << 8) | buf[2];
+
+       return 0;
+}
+
+static int mc44s803_release(struct dvb_frontend *fe)
+{
+       struct mc44s803_priv *priv = fe->tuner_priv;
+
+       fe->tuner_priv = NULL;
+       kfree(priv);
+
+       return 0;
+}
+
+static int mc44s803_init(struct dvb_frontend *fe)
+{
+       struct mc44s803_priv *priv = fe->tuner_priv;
+       u32 val;
+       int err;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+/* Reset chip */
+       val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR) |
+             MC44S803_REG_SM(1, MC44S803_RS);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+/* Power Up and Start Osc */
+
+       val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) |
+             MC44S803_REG_SM(0xC0, MC44S803_REFOSC) |
+             MC44S803_REG_SM(1, MC44S803_OSCSEL);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       val = MC44S803_REG_SM(MC44S803_REG_POWER, MC44S803_ADDR) |
+             MC44S803_REG_SM(0x200, MC44S803_POWER);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       msleep(10);
+
+       val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) |
+             MC44S803_REG_SM(0x40, MC44S803_REFOSC) |
+             MC44S803_REG_SM(1, MC44S803_OSCSEL);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       msleep(20);
+
+/* Setup Mixer */
+
+       val = MC44S803_REG_SM(MC44S803_REG_MIXER, MC44S803_ADDR) |
+             MC44S803_REG_SM(1, MC44S803_TRI_STATE) |
+             MC44S803_REG_SM(0x7F, MC44S803_MIXER_RES);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+/* Setup Cirquit Adjust */
+
+       val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) |
+             MC44S803_REG_SM(1, MC44S803_G1) |
+             MC44S803_REG_SM(1, MC44S803_G3) |
+             MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) |
+             MC44S803_REG_SM(1, MC44S803_G6) |
+             MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) |
+             MC44S803_REG_SM(0x3, MC44S803_LP) |
+             MC44S803_REG_SM(1, MC44S803_CLRF) |
+             MC44S803_REG_SM(1, MC44S803_CLIF);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) |
+             MC44S803_REG_SM(1, MC44S803_G1) |
+             MC44S803_REG_SM(1, MC44S803_G3) |
+             MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) |
+             MC44S803_REG_SM(1, MC44S803_G6) |
+             MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) |
+             MC44S803_REG_SM(0x3, MC44S803_LP);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+/* Setup Digtune */
+
+       val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
+             MC44S803_REG_SM(3, MC44S803_XOD);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+/* Setup AGC */
+
+       val = MC44S803_REG_SM(MC44S803_REG_LNAAGC, MC44S803_ADDR) |
+             MC44S803_REG_SM(1, MC44S803_AT1) |
+             MC44S803_REG_SM(1, MC44S803_AT2) |
+             MC44S803_REG_SM(1, MC44S803_AGC_AN_DIG) |
+             MC44S803_REG_SM(1, MC44S803_AGC_READ_EN) |
+             MC44S803_REG_SM(1, MC44S803_LNA0);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+       return 0;
+
+exit:
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       mc_printk(KERN_WARNING, "I/O Error\n");
+       return err;
+}
+
+static int mc44s803_set_params(struct dvb_frontend *fe)
+{
+       struct mc44s803_priv *priv = fe->tuner_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u32 r1, r2, n1, n2, lo1, lo2, freq, val;
+       int err;
+
+       priv->frequency = c->frequency;
+
+       r1 = MC44S803_OSC / 1000000;
+       r2 = MC44S803_OSC /  100000;
+
+       n1 = (c->frequency + MC44S803_IF1 + 500000) / 1000000;
+       freq = MC44S803_OSC / r1 * n1;
+       lo1 = ((60 * n1) + (r1 / 2)) / r1;
+       freq = freq - c->frequency;
+
+       n2 = (freq - MC44S803_IF2 + 50000) / 100000;
+       lo2 = ((60 * n2) + (r2 / 2)) / r2;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       val = MC44S803_REG_SM(MC44S803_REG_REFDIV, MC44S803_ADDR) |
+             MC44S803_REG_SM(r1-1, MC44S803_R1) |
+             MC44S803_REG_SM(r2-1, MC44S803_R2) |
+             MC44S803_REG_SM(1, MC44S803_REFBUF_EN);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       val = MC44S803_REG_SM(MC44S803_REG_LO1, MC44S803_ADDR) |
+             MC44S803_REG_SM(n1-2, MC44S803_LO1);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       val = MC44S803_REG_SM(MC44S803_REG_LO2, MC44S803_ADDR) |
+             MC44S803_REG_SM(n2-2, MC44S803_LO2);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
+             MC44S803_REG_SM(1, MC44S803_DA) |
+             MC44S803_REG_SM(lo1, MC44S803_LO_REF) |
+             MC44S803_REG_SM(1, MC44S803_AT);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
+             MC44S803_REG_SM(2, MC44S803_DA) |
+             MC44S803_REG_SM(lo2, MC44S803_LO_REF) |
+             MC44S803_REG_SM(1, MC44S803_AT);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       return 0;
+
+exit:
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       mc_printk(KERN_WARNING, "I/O Error\n");
+       return err;
+}
+
+static int mc44s803_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct mc44s803_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static const struct dvb_tuner_ops mc44s803_tuner_ops = {
+       .info = {
+               .name           = "Freescale MC44S803",
+               .frequency_min  =   48000000,
+               .frequency_max  = 1000000000,
+               .frequency_step =     100000,
+       },
+
+       .release       = mc44s803_release,
+       .init          = mc44s803_init,
+       .set_params    = mc44s803_set_params,
+       .get_frequency = mc44s803_get_frequency
+};
+
+/* This functions tries to identify a MC44S803 tuner by reading the ID
+   register. This is hasty. */
+struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
+        struct i2c_adapter *i2c, struct mc44s803_config *cfg)
+{
+       struct mc44s803_priv *priv;
+       u32 reg;
+       u8 id;
+       int ret;
+
+       reg = 0;
+
+       priv = kzalloc(sizeof(struct mc44s803_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->cfg = cfg;
+       priv->i2c = i2c;
+       priv->fe  = fe;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+       ret = mc44s803_readreg(priv, MC44S803_REG_ID, &reg);
+       if (ret)
+               goto error;
+
+       id = MC44S803_REG_MS(reg, MC44S803_ID);
+
+       if (id != 0x14) {
+               mc_printk(KERN_ERR, "unsupported ID "
+                      "(%x should be 0x14)\n", id);
+               goto error;
+       }
+
+       mc_printk(KERN_INFO, "successfully identified (ID = %x)\n", id);
+       memcpy(&fe->ops.tuner_ops, &mc44s803_tuner_ops,
+              sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = priv;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+       return fe;
+
+error:
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+       kfree(priv);
+       return NULL;
+}
+EXPORT_SYMBOL(mc44s803_attach);
+
+MODULE_AUTHOR("Jochen Friedrich");
+MODULE_DESCRIPTION("Freescale MC44S803 silicon tuner driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/mc44s803.h b/drivers/media/tuners/mc44s803.h
new file mode 100644 (file)
index 0000000..34f3892
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
+ *
+ *  Copyright (c) 2009 Jochen Friedrich <jochen@scram.de>
+ *
+ *  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 MC44S803_H
+#define MC44S803_H
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct mc44s803_config {
+       u8 i2c_address;
+       u8 dig_out;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_MC44S803) || \
+    (defined(CONFIG_MEDIA_TUNER_MC44S803_MODULE) && defined(MODULE))
+extern struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
+        struct i2c_adapter *i2c, struct mc44s803_config *cfg);
+#else
+static inline struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
+        struct i2c_adapter *i2c, struct mc44s803_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_MEDIA_TUNER_MC44S803 */
+
+#endif
diff --git a/drivers/media/tuners/mc44s803_priv.h b/drivers/media/tuners/mc44s803_priv.h
new file mode 100644 (file)
index 0000000..14a9278
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ *  Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
+ *
+ *  Copyright (c) 2009 Jochen Friedrich <jochen@scram.de>
+ *
+ *  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 MC44S803_PRIV_H
+#define MC44S803_PRIV_H
+
+/* This driver is based on the information available in the datasheet
+   http://www.freescale.com/files/rf_if/doc/data_sheet/MC44S803.pdf
+
+   SPI or I2C Address : 0xc0-0xc6
+
+   Reg.No | Function
+   -------------------------------------------
+       00 | Power Down
+       01 | Reference Oszillator
+       02 | Reference Dividers
+       03 | Mixer and Reference Buffer
+       04 | Reset/Serial Out
+       05 | LO 1
+       06 | LO 2
+       07 | Circuit Adjust
+       08 | Test
+       09 | Digital Tune
+       0A | LNA AGC
+       0B | Data Register Address
+       0C | Regulator Test
+       0D | VCO Test
+       0E | LNA Gain/Input Power
+       0F | ID Bits
+
+*/
+
+#define MC44S803_OSC 26000000  /* 26 MHz */
+#define MC44S803_IF1 1086000000 /* 1086 MHz */
+#define MC44S803_IF2 36125000  /* 36.125 MHz */
+
+#define MC44S803_REG_POWER     0
+#define MC44S803_REG_REFOSC    1
+#define MC44S803_REG_REFDIV    2
+#define MC44S803_REG_MIXER     3
+#define MC44S803_REG_RESET     4
+#define MC44S803_REG_LO1       5
+#define MC44S803_REG_LO2       6
+#define MC44S803_REG_CIRCADJ   7
+#define MC44S803_REG_TEST      8
+#define MC44S803_REG_DIGTUNE   9
+#define MC44S803_REG_LNAAGC    0x0A
+#define MC44S803_REG_DATAREG   0x0B
+#define MC44S803_REG_REGTEST   0x0C
+#define MC44S803_REG_VCOTEST   0x0D
+#define MC44S803_REG_LNAGAIN   0x0E
+#define MC44S803_REG_ID                0x0F
+
+/* Register definitions */
+#define MC44S803_ADDR          0x0F
+#define MC44S803_ADDR_S                0
+/* REG_POWER */
+#define MC44S803_POWER         0xFFFFF0
+#define MC44S803_POWER_S       4
+/* REG_REFOSC */
+#define MC44S803_REFOSC                0x1FF0
+#define MC44S803_REFOSC_S      4
+#define MC44S803_OSCSEL                0x2000
+#define MC44S803_OSCSEL_S      13
+/* REG_REFDIV */
+#define MC44S803_R2            0x1FF0
+#define MC44S803_R2_S          4
+#define MC44S803_REFBUF_EN     0x2000
+#define MC44S803_REFBUF_EN_S   13
+#define MC44S803_R1            0x7C000
+#define MC44S803_R1_S          14
+/* REG_MIXER */
+#define MC44S803_R3            0x70
+#define MC44S803_R3_S          4
+#define MC44S803_MUX3          0x80
+#define MC44S803_MUX3_S                7
+#define MC44S803_MUX4          0x100
+#define MC44S803_MUX4_S                8
+#define MC44S803_OSC_SCR       0x200
+#define MC44S803_OSC_SCR_S     9
+#define MC44S803_TRI_STATE     0x400
+#define MC44S803_TRI_STATE_S   10
+#define MC44S803_BUF_GAIN      0x800
+#define MC44S803_BUF_GAIN_S    11
+#define MC44S803_BUF_IO                0x1000
+#define MC44S803_BUF_IO_S      12
+#define MC44S803_MIXER_RES     0xFE000
+#define MC44S803_MIXER_RES_S   13
+/* REG_RESET */
+#define MC44S803_RS            0x10
+#define MC44S803_RS_S          4
+#define MC44S803_SO            0x20
+#define MC44S803_SO_S          5
+/* REG_LO1 */
+#define MC44S803_LO1           0xFFF0
+#define MC44S803_LO1_S         4
+/* REG_LO2 */
+#define MC44S803_LO2           0x7FFF0
+#define MC44S803_LO2_S         4
+/* REG_CIRCADJ */
+#define MC44S803_G1            0x20
+#define MC44S803_G1_S          5
+#define MC44S803_G3            0x80
+#define MC44S803_G3_S          7
+#define MC44S803_CIRCADJ_RES   0x300
+#define MC44S803_CIRCADJ_RES_S 8
+#define MC44S803_G6            0x400
+#define MC44S803_G6_S          10
+#define MC44S803_G7            0x800
+#define MC44S803_G7_S          11
+#define MC44S803_S1            0x1000
+#define MC44S803_S1_S          12
+#define MC44S803_LP            0x7E000
+#define MC44S803_LP_S          13
+#define MC44S803_CLRF          0x80000
+#define MC44S803_CLRF_S                19
+#define MC44S803_CLIF          0x100000
+#define MC44S803_CLIF_S                20
+/* REG_TEST */
+/* REG_DIGTUNE */
+#define MC44S803_DA            0xF0
+#define MC44S803_DA_S          4
+#define MC44S803_XOD           0x300
+#define MC44S803_XOD_S         8
+#define MC44S803_RST           0x10000
+#define MC44S803_RST_S         16
+#define MC44S803_LO_REF                0x1FFF00
+#define MC44S803_LO_REF_S      8
+#define MC44S803_AT            0x200000
+#define MC44S803_AT_S          21
+#define MC44S803_MT            0x400000
+#define MC44S803_MT_S          22
+/* REG_LNAAGC */
+#define MC44S803_G             0x3F0
+#define MC44S803_G_S           4
+#define MC44S803_AT1           0x400
+#define MC44S803_AT1_S         10
+#define MC44S803_AT2           0x800
+#define MC44S803_AT2_S         11
+#define MC44S803_HL_GR_EN      0x8000
+#define MC44S803_HL_GR_EN_S    15
+#define MC44S803_AGC_AN_DIG    0x10000
+#define MC44S803_AGC_AN_DIG_S  16
+#define MC44S803_ATTEN_EN      0x20000
+#define MC44S803_ATTEN_EN_S    17
+#define MC44S803_AGC_READ_EN   0x40000
+#define MC44S803_AGC_READ_EN_S 18
+#define MC44S803_LNA0          0x80000
+#define MC44S803_LNA0_S                19
+#define MC44S803_AGC_SEL       0x100000
+#define MC44S803_AGC_SEL_S     20
+#define MC44S803_AT0           0x200000
+#define MC44S803_AT0_S         21
+#define MC44S803_B             0xC00000
+#define MC44S803_B_S           22
+/* REG_DATAREG */
+#define MC44S803_D             0xF0
+#define MC44S803_D_S           4
+/* REG_REGTEST */
+/* REG_VCOTEST */
+/* REG_LNAGAIN */
+#define MC44S803_IF_PWR                0x700
+#define MC44S803_IF_PWR_S      8
+#define MC44S803_RF_PWR                0x3800
+#define MC44S803_RF_PWR_S      11
+#define MC44S803_LNA_GAIN      0xFC000
+#define MC44S803_LNA_GAIN_S    14
+/* REG_ID */
+#define MC44S803_ID            0x3E00
+#define MC44S803_ID_S          9
+
+/* Some macros to read/write fields */
+
+/* First shift, then mask */
+#define MC44S803_REG_SM(_val, _reg)                                    \
+       (((_val) << _reg##_S) & (_reg))
+
+/* First mask, then shift */
+#define MC44S803_REG_MS(_val, _reg)                                    \
+       (((_val) & (_reg)) >> _reg##_S)
+
+struct mc44s803_priv {
+       struct mc44s803_config *cfg;
+       struct i2c_adapter *i2c;
+       struct dvb_frontend *fe;
+
+       u32 frequency;
+};
+
+#endif
diff --git a/drivers/media/tuners/mt2060.c b/drivers/media/tuners/mt2060.c
new file mode 100644 (file)
index 0000000..13381de
--- /dev/null
@@ -0,0 +1,403 @@
+/*
+ *  Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
+ *
+ *  Copyright (c) 2006 Olivier DANET <odanet@caramail.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.=
+ */
+
+/* In that file, frequencies are expressed in kiloHertz to avoid 32 bits overflows */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+
+#include "mt2060.h"
+#include "mt2060_priv.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+#define dprintk(args...) do { if (debug) {printk(KERN_DEBUG "MT2060: " args); printk("\n"); }} while (0)
+
+// Reads a single register
+static int mt2060_readreg(struct mt2060_priv *priv, u8 reg, u8 *val)
+{
+       struct i2c_msg msg[2] = {
+               { .addr = priv->cfg->i2c_address, .flags = 0,        .buf = &reg, .len = 1 },
+               { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val,  .len = 1 },
+       };
+
+       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
+               printk(KERN_WARNING "mt2060 I2C read failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+// Writes a single register
+static int mt2060_writereg(struct mt2060_priv *priv, u8 reg, u8 val)
+{
+       u8 buf[2] = { reg, val };
+       struct i2c_msg msg = {
+               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2
+       };
+
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "mt2060 I2C write failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+// Writes a set of consecutive registers
+static int mt2060_writeregs(struct mt2060_priv *priv,u8 *buf, u8 len)
+{
+       struct i2c_msg msg = {
+               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = len
+       };
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "mt2060 I2C write failed (len=%i)\n",(int)len);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+// Initialisation sequences
+// LNABAND=3, NUM1=0x3C, DIV1=0x74, NUM2=0x1080, DIV2=0x49
+static u8 mt2060_config1[] = {
+       REG_LO1C1,
+       0x3F,   0x74,   0x00,   0x08,   0x93
+};
+
+// FMCG=2, GP2=0, GP1=0
+static u8 mt2060_config2[] = {
+       REG_MISC_CTRL,
+       0x20,   0x1E,   0x30,   0xff,   0x80,   0xff,   0x00,   0x2c,   0x42
+};
+
+//  VGAG=3, V1CSE=1
+
+#ifdef  MT2060_SPURCHECK
+/* The function below calculates the frequency offset between the output frequency if2
+ and the closer cross modulation subcarrier between lo1 and lo2 up to the tenth harmonic */
+static int mt2060_spurcalc(u32 lo1,u32 lo2,u32 if2)
+{
+       int I,J;
+       int dia,diamin,diff;
+       diamin=1000000;
+       for (I = 1; I < 10; I++) {
+               J = ((2*I*lo1)/lo2+1)/2;
+               diff = I*(int)lo1-J*(int)lo2;
+               if (diff < 0) diff=-diff;
+               dia = (diff-(int)if2);
+               if (dia < 0) dia=-dia;
+               if (diamin > dia) diamin=dia;
+       }
+       return diamin;
+}
+
+#define BANDWIDTH 4000 // kHz
+
+/* Calculates the frequency offset to add to avoid spurs. Returns 0 if no offset is needed */
+static int mt2060_spurcheck(u32 lo1,u32 lo2,u32 if2)
+{
+       u32 Spur,Sp1,Sp2;
+       int I,J;
+       I=0;
+       J=1000;
+
+       Spur=mt2060_spurcalc(lo1,lo2,if2);
+       if (Spur < BANDWIDTH) {
+               /* Potential spurs detected */
+               dprintk("Spurs before : f_lo1: %d  f_lo2: %d  (kHz)",
+                       (int)lo1,(int)lo2);
+               I=1000;
+               Sp1 = mt2060_spurcalc(lo1+I,lo2+I,if2);
+               Sp2 = mt2060_spurcalc(lo1-I,lo2-I,if2);
+
+               if (Sp1 < Sp2) {
+                       J=-J; I=-I; Spur=Sp2;
+               } else
+                       Spur=Sp1;
+
+               while (Spur < BANDWIDTH) {
+                       I += J;
+                       Spur = mt2060_spurcalc(lo1+I,lo2+I,if2);
+               }
+               dprintk("Spurs after  : f_lo1: %d  f_lo2: %d  (kHz)",
+                       (int)(lo1+I),(int)(lo2+I));
+       }
+       return I;
+}
+#endif
+
+#define IF2  36150       // IF2 frequency = 36.150 MHz
+#define FREF 16000       // Quartz oscillator 16 MHz
+
+static int mt2060_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct mt2060_priv *priv;
+       int ret=0;
+       int i=0;
+       u32 freq;
+       u8  lnaband;
+       u32 f_lo1,f_lo2;
+       u32 div1,num1,div2,num2;
+       u8  b[8];
+       u32 if1;
+
+       priv = fe->tuner_priv;
+
+       if1 = priv->if1_freq;
+       b[0] = REG_LO1B1;
+       b[1] = 0xFF;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+       mt2060_writeregs(priv,b,2);
+
+       freq = c->frequency / 1000; /* Hz -> kHz */
+
+       f_lo1 = freq + if1 * 1000;
+       f_lo1 = (f_lo1 / 250) * 250;
+       f_lo2 = f_lo1 - freq - IF2;
+       // From the Comtech datasheet, the step used is 50kHz. The tuner chip could be more precise
+       f_lo2 = ((f_lo2 + 25) / 50) * 50;
+       priv->frequency =  (f_lo1 - f_lo2 - IF2) * 1000,
+
+#ifdef MT2060_SPURCHECK
+       // LO-related spurs detection and correction
+       num1   = mt2060_spurcheck(f_lo1,f_lo2,IF2);
+       f_lo1 += num1;
+       f_lo2 += num1;
+#endif
+       //Frequency LO1 = 16MHz * (DIV1 + NUM1/64 )
+       num1 = f_lo1 / (FREF / 64);
+       div1 = num1 / 64;
+       num1 &= 0x3f;
+
+       // Frequency LO2 = 16MHz * (DIV2 + NUM2/8192 )
+       num2 = f_lo2 * 64 / (FREF / 128);
+       div2 = num2 / 8192;
+       num2 &= 0x1fff;
+
+       if (freq <=  95000) lnaband = 0xB0; else
+       if (freq <= 180000) lnaband = 0xA0; else
+       if (freq <= 260000) lnaband = 0x90; else
+       if (freq <= 335000) lnaband = 0x80; else
+       if (freq <= 425000) lnaband = 0x70; else
+       if (freq <= 480000) lnaband = 0x60; else
+       if (freq <= 570000) lnaband = 0x50; else
+       if (freq <= 645000) lnaband = 0x40; else
+       if (freq <= 730000) lnaband = 0x30; else
+       if (freq <= 810000) lnaband = 0x20; else lnaband = 0x10;
+
+       b[0] = REG_LO1C1;
+       b[1] = lnaband | ((num1 >>2) & 0x0F);
+       b[2] = div1;
+       b[3] = (num2 & 0x0F)  | ((num1 & 3) << 4);
+       b[4] = num2 >> 4;
+       b[5] = ((num2 >>12) & 1) | (div2 << 1);
+
+       dprintk("IF1: %dMHz",(int)if1);
+       dprintk("PLL freq=%dkHz  f_lo1=%dkHz  f_lo2=%dkHz",(int)freq,(int)f_lo1,(int)f_lo2);
+       dprintk("PLL div1=%d  num1=%d  div2=%d  num2=%d",(int)div1,(int)num1,(int)div2,(int)num2);
+       dprintk("PLL [1..5]: %2x %2x %2x %2x %2x",(int)b[1],(int)b[2],(int)b[3],(int)b[4],(int)b[5]);
+
+       mt2060_writeregs(priv,b,6);
+
+       //Waits for pll lock or timeout
+       i = 0;
+       do {
+               mt2060_readreg(priv,REG_LO_STATUS,b);
+               if ((b[0] & 0x88)==0x88)
+                       break;
+               msleep(4);
+               i++;
+       } while (i<10);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+       return ret;
+}
+
+static void mt2060_calibrate(struct mt2060_priv *priv)
+{
+       u8 b = 0;
+       int i = 0;
+
+       if (mt2060_writeregs(priv,mt2060_config1,sizeof(mt2060_config1)))
+               return;
+       if (mt2060_writeregs(priv,mt2060_config2,sizeof(mt2060_config2)))
+               return;
+
+       /* initialize the clock output */
+       mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x30);
+
+       do {
+               b |= (1 << 6); // FM1SS;
+               mt2060_writereg(priv, REG_LO2C1,b);
+               msleep(20);
+
+               if (i == 0) {
+                       b |= (1 << 7); // FM1CA;
+                       mt2060_writereg(priv, REG_LO2C1,b);
+                       b &= ~(1 << 7); // FM1CA;
+                       msleep(20);
+               }
+
+               b &= ~(1 << 6); // FM1SS
+               mt2060_writereg(priv, REG_LO2C1,b);
+
+               msleep(20);
+               i++;
+       } while (i < 9);
+
+       i = 0;
+       while (i++ < 10 && mt2060_readreg(priv, REG_MISC_STAT, &b) == 0 && (b & (1 << 6)) == 0)
+               msleep(20);
+
+       if (i <= 10) {
+               mt2060_readreg(priv, REG_FM_FREQ, &priv->fmfreq); // now find out, what is fmreq used for :)
+               dprintk("calibration was successful: %d", (int)priv->fmfreq);
+       } else
+               dprintk("FMCAL timed out");
+}
+
+static int mt2060_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct mt2060_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static int mt2060_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       *frequency = IF2 * 1000;
+       return 0;
+}
+
+static int mt2060_init(struct dvb_frontend *fe)
+{
+       struct mt2060_priv *priv = fe->tuner_priv;
+       int ret;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+       ret = mt2060_writereg(priv, REG_VGAG,
+                             (priv->cfg->clock_out << 6) | 0x33);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+       return ret;
+}
+
+static int mt2060_sleep(struct dvb_frontend *fe)
+{
+       struct mt2060_priv *priv = fe->tuner_priv;
+       int ret;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+       ret = mt2060_writereg(priv, REG_VGAG,
+                             (priv->cfg->clock_out << 6) | 0x30);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+       return ret;
+}
+
+static int mt2060_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static const struct dvb_tuner_ops mt2060_tuner_ops = {
+       .info = {
+               .name           = "Microtune MT2060",
+               .frequency_min  =  48000000,
+               .frequency_max  = 860000000,
+               .frequency_step =     50000,
+       },
+
+       .release       = mt2060_release,
+
+       .init          = mt2060_init,
+       .sleep         = mt2060_sleep,
+
+       .set_params    = mt2060_set_params,
+       .get_frequency = mt2060_get_frequency,
+       .get_if_frequency = mt2060_get_if_frequency,
+};
+
+/* This functions tries to identify a MT2060 tuner by reading the PART/REV register. This is hasty. */
+struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
+{
+       struct mt2060_priv *priv = NULL;
+       u8 id = 0;
+
+       priv = kzalloc(sizeof(struct mt2060_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->cfg      = cfg;
+       priv->i2c      = i2c;
+       priv->if1_freq = if1;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+       if (mt2060_readreg(priv,REG_PART_REV,&id) != 0) {
+               kfree(priv);
+               return NULL;
+       }
+
+       if (id != PART_REV) {
+               kfree(priv);
+               return NULL;
+       }
+       printk(KERN_INFO "MT2060: successfully identified (IF1 = %d)\n", if1);
+       memcpy(&fe->ops.tuner_ops, &mt2060_tuner_ops, sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = priv;
+
+       mt2060_calibrate(priv);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+       return fe;
+}
+EXPORT_SYMBOL(mt2060_attach);
+
+MODULE_AUTHOR("Olivier DANET");
+MODULE_DESCRIPTION("Microtune MT2060 silicon tuner driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/mt2060.h b/drivers/media/tuners/mt2060.h
new file mode 100644 (file)
index 0000000..cb60caf
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
+ *
+ *  Copyright (c) 2006 Olivier DANET <odanet@caramail.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 MT2060_H
+#define MT2060_H
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct mt2060_config {
+       u8 i2c_address;
+       u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
+};
+
+#if defined(CONFIG_MEDIA_TUNER_MT2060) || (defined(CONFIG_MEDIA_TUNER_MT2060_MODULE) && defined(MODULE))
+extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1);
+#else
+static inline struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_MEDIA_TUNER_MT2060
+
+#endif
diff --git a/drivers/media/tuners/mt2060_priv.h b/drivers/media/tuners/mt2060_priv.h
new file mode 100644 (file)
index 0000000..2b60de6
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ *  Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
+ *
+ *  Copyright (c) 2006 Olivier DANET <odanet@caramail.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 MT2060_PRIV_H
+#define MT2060_PRIV_H
+
+// Uncomment the #define below to enable spurs checking. The results where quite unconvincing.
+// #define MT2060_SPURCHECK
+
+/* This driver is based on the information available in the datasheet of the
+   "Comtech SDVBT-3K6M" tuner ( K1000737843.pdf ) which features the MT2060 register map :
+
+   I2C Address : 0x60
+
+   Reg.No |   B7   |   B6   |   B5   |   B4   |   B3   |   B2   |   B1   |   B0   | ( defaults )
+   --------------------------------------------------------------------------------
+       00 | [              PART             ] | [              REV              ] | R  = 0x63
+       01 | [             LNABAND           ] | [              NUM1(5:2)        ] | RW = 0x3F
+       02 | [                               DIV1                                ] | RW = 0x74
+       03 | FM1CA  | FM1SS  | [  NUM1(1:0)  ] | [              NUM2(3:0)        ] | RW = 0x00
+       04 |                                 NUM2(11:4)                          ] | RW = 0x08
+       05 | [                               DIV2                       ] |NUM2(12)| RW = 0x93
+       06 | L1LK   | [        TAD1          ] | L2LK   | [         TAD2         ] | R
+       07 | [                               FMF                                 ] | R
+       08 |   ?    | FMCAL  |   ?    |   ?    |   ?    |   ?    |   ?    | TEMP   | R
+       09 |   0    |   0    | [    FMGC     ] |   0    | GP02   | GP01   |   0    | RW = 0x20
+       0A | ??
+       0B |   0    |   0    |   1    |   1    |   0    |   0    | [   VGAG      ] | RW = 0x30
+       0C | V1CSE  |   1    |   1    |   1    |   1    |   1    |   1    |   1    | RW = 0xFF
+       0D |   1    |   0    | [                      V1CS                       ] | RW = 0xB0
+       0E | ??
+       0F | ??
+       10 | ??
+       11 | [             LOTO              ] |   0    |   0    |   1    |   0    | RW = 0x42
+
+       PART    : Part code      : 6 for MT2060
+       REV     : Revision code  : 3 for current revision
+       LNABAND : Input frequency range : ( See code for details )
+       NUM1 / DIV1 / NUM2 / DIV2 : Frequencies programming ( See code for details )
+       FM1CA  : Calibration Start Bit
+       FM1SS  : Calibration Single Step bit
+       L1LK   : LO1 Lock Detect
+       TAD1   : Tune Line ADC ( ? )
+       L2LK   : LO2 Lock Detect
+       TAD2   : Tune Line ADC ( ? )
+       FMF    : Estimated first IF Center frequency Offset ( ? )
+       FM1CAL : Calibration done bit
+       TEMP   : On chip temperature sensor
+       FMCG   : Mixer 1 Cap Gain ( ? )
+       GP01 / GP02 : Programmable digital outputs. Unconnected pins ?
+       V1CSE  : LO1 VCO Automatic Capacitor Select Enable ( ? )
+       V1CS   : LO1 Capacitor Selection Value ( ? )
+       LOTO   : LO Timeout ( ? )
+       VGAG   : Tuner Output gain
+*/
+
+#define I2C_ADDRESS 0x60
+
+#define REG_PART_REV   0
+#define REG_LO1C1      1
+#define REG_LO1C2      2
+#define REG_LO2C1      3
+#define REG_LO2C2      4
+#define REG_LO2C3      5
+#define REG_LO_STATUS  6
+#define REG_FM_FREQ    7
+#define REG_MISC_STAT  8
+#define REG_MISC_CTRL  9
+#define REG_RESERVED_A 0x0A
+#define REG_VGAG       0x0B
+#define REG_LO1B1      0x0C
+#define REG_LO1B2      0x0D
+#define REG_LOTO       0x11
+
+#define PART_REV 0x63 // The current driver works only with PART=6 and REV=3 chips
+
+struct mt2060_priv {
+       struct mt2060_config *cfg;
+       struct i2c_adapter   *i2c;
+
+       u32 frequency;
+       u16 if1_freq;
+       u8  fmfreq;
+};
+
+#endif
diff --git a/drivers/media/tuners/mt2063.c b/drivers/media/tuners/mt2063.c
new file mode 100644 (file)
index 0000000..0ed9091
--- /dev/null
@@ -0,0 +1,2307 @@
+/*
+ * Driver for mt2063 Micronas tuner
+ *
+ * Copyright (c) 2011 Mauro Carvalho Chehab <mchehab@redhat.com>
+ *
+ * This driver came from a driver originally written by:
+ *             Henry Wang <Henry.wang@AzureWave.com>
+ * Made publicly available by Terratec, at:
+ *     http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz
+ * The original driver's license is GPL, as declared with MODULE_LICENSE()
+ *
+ * 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 under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/videodev2.h>
+
+#include "mt2063.h"
+
+static unsigned int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Set Verbosity level");
+
+#define dprintk(level, fmt, arg...) do {                               \
+if (debug >= level)                                                    \
+       printk(KERN_DEBUG "mt2063 %s: " fmt, __func__, ## arg); \
+} while (0)
+
+
+/* positive error codes used internally */
+
+/*  Info: Unavoidable LO-related spur may be present in the output  */
+#define MT2063_SPUR_PRESENT_ERR             (0x00800000)
+
+/*  Info: Mask of bits used for # of LO-related spurs that were avoided during tuning  */
+#define MT2063_SPUR_CNT_MASK                (0x001f0000)
+#define MT2063_SPUR_SHIFT                   (16)
+
+/*  Info: Upconverter frequency is out of range (may be reason for MT_UPC_UNLOCK) */
+#define MT2063_UPC_RANGE                    (0x04000000)
+
+/*  Info: Downconverter frequency is out of range (may be reason for MT_DPC_UNLOCK) */
+#define MT2063_DNC_RANGE                    (0x08000000)
+
+/*
+ *  Constant defining the version of the following structure
+ *  and therefore the API for this code.
+ *
+ *  When compiling the tuner driver, the preprocessor will
+ *  check against this version number to make sure that
+ *  it matches the version that the tuner driver knows about.
+ */
+
+/* DECT Frequency Avoidance */
+#define MT2063_DECT_AVOID_US_FREQS      0x00000001
+
+#define MT2063_DECT_AVOID_EURO_FREQS    0x00000002
+
+#define MT2063_EXCLUDE_US_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_US_FREQS) != 0)
+
+#define MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_EURO_FREQS) != 0)
+
+enum MT2063_DECT_Avoid_Type {
+       MT2063_NO_DECT_AVOIDANCE = 0,                           /* Do not create DECT exclusion zones.     */
+       MT2063_AVOID_US_DECT = MT2063_DECT_AVOID_US_FREQS,      /* Avoid US DECT frequencies.              */
+       MT2063_AVOID_EURO_DECT = MT2063_DECT_AVOID_EURO_FREQS,  /* Avoid European DECT frequencies.        */
+       MT2063_AVOID_BOTH                                       /* Avoid both regions. Not typically used. */
+};
+
+#define MT2063_MAX_ZONES 48
+
+struct MT2063_ExclZone_t {
+       u32 min_;
+       u32 max_;
+       struct MT2063_ExclZone_t *next_;
+};
+
+/*
+ *  Structure of data needed for Spur Avoidance
+ */
+struct MT2063_AvoidSpursData_t {
+       u32 f_ref;
+       u32 f_in;
+       u32 f_LO1;
+       u32 f_if1_Center;
+       u32 f_if1_Request;
+       u32 f_if1_bw;
+       u32 f_LO2;
+       u32 f_out;
+       u32 f_out_bw;
+       u32 f_LO1_Step;
+       u32 f_LO2_Step;
+       u32 f_LO1_FracN_Avoid;
+       u32 f_LO2_FracN_Avoid;
+       u32 f_zif_bw;
+       u32 f_min_LO_Separation;
+       u32 maxH1;
+       u32 maxH2;
+       enum MT2063_DECT_Avoid_Type avoidDECT;
+       u32 bSpurPresent;
+       u32 bSpurAvoided;
+       u32 nSpursFound;
+       u32 nZones;
+       struct MT2063_ExclZone_t *freeZones;
+       struct MT2063_ExclZone_t *usedZones;
+       struct MT2063_ExclZone_t MT2063_ExclZones[MT2063_MAX_ZONES];
+};
+
+/*
+ * Parameter for function MT2063_SetPowerMask that specifies the power down
+ * of various sections of the MT2063.
+ */
+enum MT2063_Mask_Bits {
+       MT2063_REG_SD = 0x0040,         /* Shutdown regulator                 */
+       MT2063_SRO_SD = 0x0020,         /* Shutdown SRO                       */
+       MT2063_AFC_SD = 0x0010,         /* Shutdown AFC A/D                   */
+       MT2063_PD_SD = 0x0002,          /* Enable power detector shutdown     */
+       MT2063_PDADC_SD = 0x0001,       /* Enable power detector A/D shutdown */
+       MT2063_VCO_SD = 0x8000,         /* Enable VCO shutdown                */
+       MT2063_LTX_SD = 0x4000,         /* Enable LTX shutdown                */
+       MT2063_LT1_SD = 0x2000,         /* Enable LT1 shutdown                */
+       MT2063_LNA_SD = 0x1000,         /* Enable LNA shutdown                */
+       MT2063_UPC_SD = 0x0800,         /* Enable upconverter shutdown        */
+       MT2063_DNC_SD = 0x0400,         /* Enable downconverter shutdown      */
+       MT2063_VGA_SD = 0x0200,         /* Enable VGA shutdown                */
+       MT2063_AMP_SD = 0x0100,         /* Enable AMP shutdown                */
+       MT2063_ALL_SD = 0xFF73,         /* All shutdown bits for this tuner   */
+       MT2063_NONE_SD = 0x0000         /* No shutdown bits                   */
+};
+
+/*
+ *  Possible values for MT2063_DNC_OUTPUT
+ */
+enum MT2063_DNC_Output_Enable {
+       MT2063_DNC_NONE = 0,
+       MT2063_DNC_1,
+       MT2063_DNC_2,
+       MT2063_DNC_BOTH
+};
+
+/*
+ *  Two-wire serial bus subaddresses of the tuner registers.
+ *  Also known as the tuner's register addresses.
+ */
+enum MT2063_Register_Offsets {
+       MT2063_REG_PART_REV = 0,        /*  0x00: Part/Rev Code         */
+       MT2063_REG_LO1CQ_1,             /*  0x01: LO1C Queued Byte 1    */
+       MT2063_REG_LO1CQ_2,             /*  0x02: LO1C Queued Byte 2    */
+       MT2063_REG_LO2CQ_1,             /*  0x03: LO2C Queued Byte 1    */
+       MT2063_REG_LO2CQ_2,             /*  0x04: LO2C Queued Byte 2    */
+       MT2063_REG_LO2CQ_3,             /*  0x05: LO2C Queued Byte 3    */
+       MT2063_REG_RSVD_06,             /*  0x06: Reserved              */
+       MT2063_REG_LO_STATUS,           /*  0x07: LO Status             */
+       MT2063_REG_FIFFC,               /*  0x08: FIFF Center           */
+       MT2063_REG_CLEARTUNE,           /*  0x09: ClearTune Filter      */
+       MT2063_REG_ADC_OUT,             /*  0x0A: ADC_OUT               */
+       MT2063_REG_LO1C_1,              /*  0x0B: LO1C Byte 1           */
+       MT2063_REG_LO1C_2,              /*  0x0C: LO1C Byte 2           */
+       MT2063_REG_LO2C_1,              /*  0x0D: LO2C Byte 1           */
+       MT2063_REG_LO2C_2,              /*  0x0E: LO2C Byte 2           */
+       MT2063_REG_LO2C_3,              /*  0x0F: LO2C Byte 3           */
+       MT2063_REG_RSVD_10,             /*  0x10: Reserved              */
+       MT2063_REG_PWR_1,               /*  0x11: PWR Byte 1            */
+       MT2063_REG_PWR_2,               /*  0x12: PWR Byte 2            */
+       MT2063_REG_TEMP_STATUS,         /*  0x13: Temp Status           */
+       MT2063_REG_XO_STATUS,           /*  0x14: Crystal Status        */
+       MT2063_REG_RF_STATUS,           /*  0x15: RF Attn Status        */
+       MT2063_REG_FIF_STATUS,          /*  0x16: FIF Attn Status       */
+       MT2063_REG_LNA_OV,              /*  0x17: LNA Attn Override     */
+       MT2063_REG_RF_OV,               /*  0x18: RF Attn Override      */
+       MT2063_REG_FIF_OV,              /*  0x19: FIF Attn Override     */
+       MT2063_REG_LNA_TGT,             /*  0x1A: Reserved              */
+       MT2063_REG_PD1_TGT,             /*  0x1B: Pwr Det 1 Target      */
+       MT2063_REG_PD2_TGT,             /*  0x1C: Pwr Det 2 Target      */
+       MT2063_REG_RSVD_1D,             /*  0x1D: Reserved              */
+       MT2063_REG_RSVD_1E,             /*  0x1E: Reserved              */
+       MT2063_REG_RSVD_1F,             /*  0x1F: Reserved              */
+       MT2063_REG_RSVD_20,             /*  0x20: Reserved              */
+       MT2063_REG_BYP_CTRL,            /*  0x21: Bypass Control        */
+       MT2063_REG_RSVD_22,             /*  0x22: Reserved              */
+       MT2063_REG_RSVD_23,             /*  0x23: Reserved              */
+       MT2063_REG_RSVD_24,             /*  0x24: Reserved              */
+       MT2063_REG_RSVD_25,             /*  0x25: Reserved              */
+       MT2063_REG_RSVD_26,             /*  0x26: Reserved              */
+       MT2063_REG_RSVD_27,             /*  0x27: Reserved              */
+       MT2063_REG_FIFF_CTRL,           /*  0x28: FIFF Control          */
+       MT2063_REG_FIFF_OFFSET,         /*  0x29: FIFF Offset           */
+       MT2063_REG_CTUNE_CTRL,          /*  0x2A: Reserved              */
+       MT2063_REG_CTUNE_OV,            /*  0x2B: Reserved              */
+       MT2063_REG_CTRL_2C,             /*  0x2C: Reserved              */
+       MT2063_REG_FIFF_CTRL2,          /*  0x2D: Fiff Control          */
+       MT2063_REG_RSVD_2E,             /*  0x2E: Reserved              */
+       MT2063_REG_DNC_GAIN,            /*  0x2F: DNC Control           */
+       MT2063_REG_VGA_GAIN,            /*  0x30: VGA Gain Ctrl         */
+       MT2063_REG_RSVD_31,             /*  0x31: Reserved              */
+       MT2063_REG_TEMP_SEL,            /*  0x32: Temperature Selection */
+       MT2063_REG_RSVD_33,             /*  0x33: Reserved              */
+       MT2063_REG_RSVD_34,             /*  0x34: Reserved              */
+       MT2063_REG_RSVD_35,             /*  0x35: Reserved              */
+       MT2063_REG_RSVD_36,             /*  0x36: Reserved              */
+       MT2063_REG_RSVD_37,             /*  0x37: Reserved              */
+       MT2063_REG_RSVD_38,             /*  0x38: Reserved              */
+       MT2063_REG_RSVD_39,             /*  0x39: Reserved              */
+       MT2063_REG_RSVD_3A,             /*  0x3A: Reserved              */
+       MT2063_REG_RSVD_3B,             /*  0x3B: Reserved              */
+       MT2063_REG_RSVD_3C,             /*  0x3C: Reserved              */
+       MT2063_REG_END_REGS
+};
+
+struct mt2063_state {
+       struct i2c_adapter *i2c;
+
+       bool init;
+
+       const struct mt2063_config *config;
+       struct dvb_tuner_ops ops;
+       struct dvb_frontend *frontend;
+       struct tuner_state status;
+
+       u32 frequency;
+       u32 srate;
+       u32 bandwidth;
+       u32 reference;
+
+       u32 tuner_id;
+       struct MT2063_AvoidSpursData_t AS_Data;
+       u32 f_IF1_actual;
+       u32 rcvr_mode;
+       u32 ctfilt_sw;
+       u32 CTFiltMax[31];
+       u32 num_regs;
+       u8 reg[MT2063_REG_END_REGS];
+};
+
+/*
+ * mt2063_write - Write data into the I2C bus
+ */
+static u32 mt2063_write(struct mt2063_state *state, u8 reg, u8 *data, u32 len)
+{
+       struct dvb_frontend *fe = state->frontend;
+       int ret;
+       u8 buf[60];
+       struct i2c_msg msg = {
+               .addr = state->config->tuner_address,
+               .flags = 0,
+               .buf = buf,
+               .len = len + 1
+       };
+
+       dprintk(2, "\n");
+
+       msg.buf[0] = reg;
+       memcpy(msg.buf + 1, data, len);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       ret = i2c_transfer(state->i2c, &msg, 1);
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       if (ret < 0)
+               printk(KERN_ERR "%s error ret=%d\n", __func__, ret);
+
+       return ret;
+}
+
+/*
+ * mt2063_write - Write register data into the I2C bus, caching the value
+ */
+static u32 mt2063_setreg(struct mt2063_state *state, u8 reg, u8 val)
+{
+       u32 status;
+
+       dprintk(2, "\n");
+
+       if (reg >= MT2063_REG_END_REGS)
+               return -ERANGE;
+
+       status = mt2063_write(state, reg, &val, 1);
+       if (status < 0)
+               return status;
+
+       state->reg[reg] = val;
+
+       return 0;
+}
+
+/*
+ * mt2063_read - Read data from the I2C bus
+ */
+static u32 mt2063_read(struct mt2063_state *state,
+                          u8 subAddress, u8 *pData, u32 cnt)
+{
+       u32 status = 0; /* Status to be returned        */
+       struct dvb_frontend *fe = state->frontend;
+       u32 i = 0;
+
+       dprintk(2, "addr 0x%02x, cnt %d\n", subAddress, cnt);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       for (i = 0; i < cnt; i++) {
+               u8 b0[] = { subAddress + i };
+               struct i2c_msg msg[] = {
+                       {
+                               .addr = state->config->tuner_address,
+                               .flags = 0,
+                               .buf = b0,
+                               .len = 1
+                       }, {
+                               .addr = state->config->tuner_address,
+                               .flags = I2C_M_RD,
+                               .buf = pData + i,
+                               .len = 1
+                       }
+               };
+
+               status = i2c_transfer(state->i2c, msg, 2);
+               dprintk(2, "addr 0x%02x, ret = %d, val = 0x%02x\n",
+                          subAddress + i, status, *(pData + i));
+               if (status < 0)
+                       break;
+       }
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       if (status < 0)
+               printk(KERN_ERR "Can't read from address 0x%02x,\n",
+                      subAddress + i);
+
+       return status;
+}
+
+/*
+ * FIXME: Is this really needed?
+ */
+static int MT2063_Sleep(struct dvb_frontend *fe)
+{
+       /*
+        *  ToDo:  Add code here to implement a OS blocking
+        */
+       msleep(100);
+
+       return 0;
+}
+
+/*
+ * Microtune spur avoidance
+ */
+
+/*  Implement ceiling, floor functions.  */
+#define ceil(n, d) (((n) < 0) ? (-((-(n))/(d))) : (n)/(d) + ((n)%(d) != 0))
+#define floor(n, d) (((n) < 0) ? (-((-(n))/(d))) - ((n)%(d) != 0) : (n)/(d))
+
+struct MT2063_FIFZone_t {
+       s32 min_;
+       s32 max_;
+};
+
+static struct MT2063_ExclZone_t *InsertNode(struct MT2063_AvoidSpursData_t
+                                           *pAS_Info,
+                                           struct MT2063_ExclZone_t *pPrevNode)
+{
+       struct MT2063_ExclZone_t *pNode;
+
+       dprintk(2, "\n");
+
+       /*  Check for a node in the free list  */
+       if (pAS_Info->freeZones != NULL) {
+               /*  Use one from the free list  */
+               pNode = pAS_Info->freeZones;
+               pAS_Info->freeZones = pNode->next_;
+       } else {
+               /*  Grab a node from the array  */
+               pNode = &pAS_Info->MT2063_ExclZones[pAS_Info->nZones];
+       }
+
+       if (pPrevNode != NULL) {
+               pNode->next_ = pPrevNode->next_;
+               pPrevNode->next_ = pNode;
+       } else {                /*  insert at the beginning of the list  */
+
+               pNode->next_ = pAS_Info->usedZones;
+               pAS_Info->usedZones = pNode;
+       }
+
+       pAS_Info->nZones++;
+       return pNode;
+}
+
+static struct MT2063_ExclZone_t *RemoveNode(struct MT2063_AvoidSpursData_t
+                                           *pAS_Info,
+                                           struct MT2063_ExclZone_t *pPrevNode,
+                                           struct MT2063_ExclZone_t
+                                           *pNodeToRemove)
+{
+       struct MT2063_ExclZone_t *pNext = pNodeToRemove->next_;
+
+       dprintk(2, "\n");
+
+       /*  Make previous node point to the subsequent node  */
+       if (pPrevNode != NULL)
+               pPrevNode->next_ = pNext;
+
+       /*  Add pNodeToRemove to the beginning of the freeZones  */
+       pNodeToRemove->next_ = pAS_Info->freeZones;
+       pAS_Info->freeZones = pNodeToRemove;
+
+       /*  Decrement node count  */
+       pAS_Info->nZones--;
+
+       return pNext;
+}
+
+/*
+ * MT_AddExclZone()
+ *
+ * Add (and merge) an exclusion zone into the list.
+ * If the range (f_min, f_max) is totally outside the
+ * 1st IF BW, ignore the entry.
+ * If the range (f_min, f_max) is negative, ignore the entry.
+ */
+static void MT2063_AddExclZone(struct MT2063_AvoidSpursData_t *pAS_Info,
+                              u32 f_min, u32 f_max)
+{
+       struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
+       struct MT2063_ExclZone_t *pPrev = NULL;
+       struct MT2063_ExclZone_t *pNext = NULL;
+
+       dprintk(2, "\n");
+
+       /*  Check to see if this overlaps the 1st IF filter  */
+       if ((f_max > (pAS_Info->f_if1_Center - (pAS_Info->f_if1_bw / 2)))
+           && (f_min < (pAS_Info->f_if1_Center + (pAS_Info->f_if1_bw / 2)))
+           && (f_min < f_max)) {
+               /*
+                *                1        2         3      4       5        6
+                *
+                *   New entry:  |---|    |--|      |--|    |-|    |---|    |--|
+                *                or       or        or     or      or
+                *   Existing:  |--|      |--|      |--|    |---|  |-|      |--|
+                */
+
+               /*  Check for our place in the list  */
+               while ((pNode != NULL) && (pNode->max_ < f_min)) {
+                       pPrev = pNode;
+                       pNode = pNode->next_;
+               }
+
+               if ((pNode != NULL) && (pNode->min_ < f_max)) {
+                       /*  Combine me with pNode  */
+                       if (f_min < pNode->min_)
+                               pNode->min_ = f_min;
+                       if (f_max > pNode->max_)
+                               pNode->max_ = f_max;
+               } else {
+                       pNode = InsertNode(pAS_Info, pPrev);
+                       pNode->min_ = f_min;
+                       pNode->max_ = f_max;
+               }
+
+               /*  Look for merging possibilities  */
+               pNext = pNode->next_;
+               while ((pNext != NULL) && (pNext->min_ < pNode->max_)) {
+                       if (pNext->max_ > pNode->max_)
+                               pNode->max_ = pNext->max_;
+                       /*  Remove pNext, return ptr to pNext->next  */
+                       pNext = RemoveNode(pAS_Info, pNode, pNext);
+               }
+       }
+}
+
+/*
+ *  Reset all exclusion zones.
+ *  Add zones to protect the PLL FracN regions near zero
+ */
+static void MT2063_ResetExclZones(struct MT2063_AvoidSpursData_t *pAS_Info)
+{
+       u32 center;
+
+       dprintk(2, "\n");
+
+       pAS_Info->nZones = 0;   /*  this clears the used list  */
+       pAS_Info->usedZones = NULL;     /*  reset ptr                  */
+       pAS_Info->freeZones = NULL;     /*  reset ptr                  */
+
+       center =
+           pAS_Info->f_ref *
+           ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 +
+             pAS_Info->f_in) / pAS_Info->f_ref) - pAS_Info->f_in;
+       while (center <
+              pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
+              pAS_Info->f_LO1_FracN_Avoid) {
+               /*  Exclude LO1 FracN  */
+               MT2063_AddExclZone(pAS_Info,
+                                  center - pAS_Info->f_LO1_FracN_Avoid,
+                                  center - 1);
+               MT2063_AddExclZone(pAS_Info, center + 1,
+                                  center + pAS_Info->f_LO1_FracN_Avoid);
+               center += pAS_Info->f_ref;
+       }
+
+       center =
+           pAS_Info->f_ref *
+           ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 -
+             pAS_Info->f_out) / pAS_Info->f_ref) + pAS_Info->f_out;
+       while (center <
+              pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
+              pAS_Info->f_LO2_FracN_Avoid) {
+               /*  Exclude LO2 FracN  */
+               MT2063_AddExclZone(pAS_Info,
+                                  center - pAS_Info->f_LO2_FracN_Avoid,
+                                  center - 1);
+               MT2063_AddExclZone(pAS_Info, center + 1,
+                                  center + pAS_Info->f_LO2_FracN_Avoid);
+               center += pAS_Info->f_ref;
+       }
+
+       if (MT2063_EXCLUDE_US_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
+               /*  Exclude LO1 values that conflict with DECT channels */
+               MT2063_AddExclZone(pAS_Info, 1920836000 - pAS_Info->f_in, 1922236000 - pAS_Info->f_in); /* Ctr = 1921.536 */
+               MT2063_AddExclZone(pAS_Info, 1922564000 - pAS_Info->f_in, 1923964000 - pAS_Info->f_in); /* Ctr = 1923.264 */
+               MT2063_AddExclZone(pAS_Info, 1924292000 - pAS_Info->f_in, 1925692000 - pAS_Info->f_in); /* Ctr = 1924.992 */
+               MT2063_AddExclZone(pAS_Info, 1926020000 - pAS_Info->f_in, 1927420000 - pAS_Info->f_in); /* Ctr = 1926.720 */
+               MT2063_AddExclZone(pAS_Info, 1927748000 - pAS_Info->f_in, 1929148000 - pAS_Info->f_in); /* Ctr = 1928.448 */
+       }
+
+       if (MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
+               MT2063_AddExclZone(pAS_Info, 1896644000 - pAS_Info->f_in, 1898044000 - pAS_Info->f_in); /* Ctr = 1897.344 */
+               MT2063_AddExclZone(pAS_Info, 1894916000 - pAS_Info->f_in, 1896316000 - pAS_Info->f_in); /* Ctr = 1895.616 */
+               MT2063_AddExclZone(pAS_Info, 1893188000 - pAS_Info->f_in, 1894588000 - pAS_Info->f_in); /* Ctr = 1893.888 */
+               MT2063_AddExclZone(pAS_Info, 1891460000 - pAS_Info->f_in, 1892860000 - pAS_Info->f_in); /* Ctr = 1892.16  */
+               MT2063_AddExclZone(pAS_Info, 1889732000 - pAS_Info->f_in, 1891132000 - pAS_Info->f_in); /* Ctr = 1890.432 */
+               MT2063_AddExclZone(pAS_Info, 1888004000 - pAS_Info->f_in, 1889404000 - pAS_Info->f_in); /* Ctr = 1888.704 */
+               MT2063_AddExclZone(pAS_Info, 1886276000 - pAS_Info->f_in, 1887676000 - pAS_Info->f_in); /* Ctr = 1886.976 */
+               MT2063_AddExclZone(pAS_Info, 1884548000 - pAS_Info->f_in, 1885948000 - pAS_Info->f_in); /* Ctr = 1885.248 */
+               MT2063_AddExclZone(pAS_Info, 1882820000 - pAS_Info->f_in, 1884220000 - pAS_Info->f_in); /* Ctr = 1883.52  */
+               MT2063_AddExclZone(pAS_Info, 1881092000 - pAS_Info->f_in, 1882492000 - pAS_Info->f_in); /* Ctr = 1881.792 */
+       }
+}
+
+/*
+ * MT_ChooseFirstIF - Choose the best available 1st IF
+ *                    If f_Desired is not excluded, choose that first.
+ *                    Otherwise, return the value closest to f_Center that is
+ *                    not excluded
+ */
+static u32 MT2063_ChooseFirstIF(struct MT2063_AvoidSpursData_t *pAS_Info)
+{
+       /*
+        * Update "f_Desired" to be the nearest "combinational-multiple" of
+        * "f_LO1_Step".
+        * The resulting number, F_LO1 must be a multiple of f_LO1_Step.
+        * And F_LO1 is the arithmetic sum of f_in + f_Center.
+        * Neither f_in, nor f_Center must be a multiple of f_LO1_Step.
+        * However, the sum must be.
+        */
+       const u32 f_Desired =
+           pAS_Info->f_LO1_Step *
+           ((pAS_Info->f_if1_Request + pAS_Info->f_in +
+             pAS_Info->f_LO1_Step / 2) / pAS_Info->f_LO1_Step) -
+           pAS_Info->f_in;
+       const u32 f_Step =
+           (pAS_Info->f_LO1_Step >
+            pAS_Info->f_LO2_Step) ? pAS_Info->f_LO1_Step : pAS_Info->
+           f_LO2_Step;
+       u32 f_Center;
+       s32 i;
+       s32 j = 0;
+       u32 bDesiredExcluded = 0;
+       u32 bZeroExcluded = 0;
+       s32 tmpMin, tmpMax;
+       s32 bestDiff;
+       struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
+       struct MT2063_FIFZone_t zones[MT2063_MAX_ZONES];
+
+       dprintk(2, "\n");
+
+       if (pAS_Info->nZones == 0)
+               return f_Desired;
+
+       /*
+        *  f_Center needs to be an integer multiple of f_Step away
+        *  from f_Desired
+        */
+       if (pAS_Info->f_if1_Center > f_Desired)
+               f_Center =
+                   f_Desired +
+                   f_Step *
+                   ((pAS_Info->f_if1_Center - f_Desired +
+                     f_Step / 2) / f_Step);
+       else
+               f_Center =
+                   f_Desired -
+                   f_Step *
+                   ((f_Desired - pAS_Info->f_if1_Center +
+                     f_Step / 2) / f_Step);
+
+       /*
+        * Take MT_ExclZones, center around f_Center and change the
+        * resolution to f_Step
+        */
+       while (pNode != NULL) {
+               /*  floor function  */
+               tmpMin =
+                   floor((s32) (pNode->min_ - f_Center), (s32) f_Step);
+
+               /*  ceil function  */
+               tmpMax =
+                   ceil((s32) (pNode->max_ - f_Center), (s32) f_Step);
+
+               if ((pNode->min_ < f_Desired) && (pNode->max_ > f_Desired))
+                       bDesiredExcluded = 1;
+
+               if ((tmpMin < 0) && (tmpMax > 0))
+                       bZeroExcluded = 1;
+
+               /*  See if this zone overlaps the previous  */
+               if ((j > 0) && (tmpMin < zones[j - 1].max_))
+                       zones[j - 1].max_ = tmpMax;
+               else {
+                       /*  Add new zone  */
+                       zones[j].min_ = tmpMin;
+                       zones[j].max_ = tmpMax;
+                       j++;
+               }
+               pNode = pNode->next_;
+       }
+
+       /*
+        *  If the desired is okay, return with it
+        */
+       if (bDesiredExcluded == 0)
+               return f_Desired;
+
+       /*
+        *  If the desired is excluded and the center is okay, return with it
+        */
+       if (bZeroExcluded == 0)
+               return f_Center;
+
+       /*  Find the value closest to 0 (f_Center)  */
+       bestDiff = zones[0].min_;
+       for (i = 0; i < j; i++) {
+               if (abs(zones[i].min_) < abs(bestDiff))
+                       bestDiff = zones[i].min_;
+               if (abs(zones[i].max_) < abs(bestDiff))
+                       bestDiff = zones[i].max_;
+       }
+
+       if (bestDiff < 0)
+               return f_Center - ((u32) (-bestDiff) * f_Step);
+
+       return f_Center + (bestDiff * f_Step);
+}
+
+/**
+ * gcd() - Uses Euclid's algorithm
+ *
+ * @u, @v:     Unsigned values whose GCD is desired.
+ *
+ * Returns THE greatest common divisor of u and v, if either value is 0,
+ * the other value is returned as the result.
+ */
+static u32 MT2063_gcd(u32 u, u32 v)
+{
+       u32 r;
+
+       while (v != 0) {
+               r = u % v;
+               u = v;
+               v = r;
+       }
+
+       return u;
+}
+
+/**
+ * IsSpurInBand() - Checks to see if a spur will be present within the IF's
+ *                  bandwidth. (fIFOut +/- fIFBW, -fIFOut +/- fIFBW)
+ *
+ *                    ma   mb                                     mc   md
+ *                  <--+-+-+-------------------+-------------------+-+-+-->
+ *                     |   ^                   0                   ^   |
+ *                     ^   b=-fIFOut+fIFBW/2      -b=+fIFOut-fIFBW/2   ^
+ *                     a=-fIFOut-fIFBW/2              -a=+fIFOut+fIFBW/2
+ *
+ *                  Note that some equations are doubled to prevent round-off
+ *                  problems when calculating fIFBW/2
+ *
+ * @pAS_Info:  Avoid Spurs information block
+ * @fm:                If spur, amount f_IF1 has to move negative
+ * @fp:                If spur, amount f_IF1 has to move positive
+ *
+ *  Returns 1 if an LO spur would be present, otherwise 0.
+ */
+static u32 IsSpurInBand(struct MT2063_AvoidSpursData_t *pAS_Info,
+                       u32 *fm, u32 * fp)
+{
+       /*
+        **  Calculate LO frequency settings.
+        */
+       u32 n, n0;
+       const u32 f_LO1 = pAS_Info->f_LO1;
+       const u32 f_LO2 = pAS_Info->f_LO2;
+       const u32 d = pAS_Info->f_out + pAS_Info->f_out_bw / 2;
+       const u32 c = d - pAS_Info->f_out_bw;
+       const u32 f = pAS_Info->f_zif_bw / 2;
+       const u32 f_Scale = (f_LO1 / (UINT_MAX / 2 / pAS_Info->maxH1)) + 1;
+       s32 f_nsLO1, f_nsLO2;
+       s32 f_Spur;
+       u32 ma, mb, mc, md, me, mf;
+       u32 lo_gcd, gd_Scale, gc_Scale, gf_Scale, hgds, hgfs, hgcs;
+
+       dprintk(2, "\n");
+
+       *fm = 0;
+
+       /*
+        ** For each edge (d, c & f), calculate a scale, based on the gcd
+        ** of f_LO1, f_LO2 and the edge value.  Use the larger of this
+        ** gcd-based scale factor or f_Scale.
+        */
+       lo_gcd = MT2063_gcd(f_LO1, f_LO2);
+       gd_Scale = max((u32) MT2063_gcd(lo_gcd, d), f_Scale);
+       hgds = gd_Scale / 2;
+       gc_Scale = max((u32) MT2063_gcd(lo_gcd, c), f_Scale);
+       hgcs = gc_Scale / 2;
+       gf_Scale = max((u32) MT2063_gcd(lo_gcd, f), f_Scale);
+       hgfs = gf_Scale / 2;
+
+       n0 = DIV_ROUND_UP(f_LO2 - d, f_LO1 - f_LO2);
+
+       /*  Check out all multiples of LO1 from n0 to m_maxLOSpurHarmonic  */
+       for (n = n0; n <= pAS_Info->maxH1; ++n) {
+               md = (n * ((f_LO1 + hgds) / gd_Scale) -
+                     ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
+
+               /*  If # fLO2 harmonics > m_maxLOSpurHarmonic, then no spurs present  */
+               if (md >= pAS_Info->maxH1)
+                       break;
+
+               ma = (n * ((f_LO1 + hgds) / gd_Scale) +
+                     ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
+
+               /*  If no spurs between +/- (f_out + f_IFBW/2), then try next harmonic  */
+               if (md == ma)
+                       continue;
+
+               mc = (n * ((f_LO1 + hgcs) / gc_Scale) -
+                     ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
+               if (mc != md) {
+                       f_nsLO1 = (s32) (n * (f_LO1 / gc_Scale));
+                       f_nsLO2 = (s32) (mc * (f_LO2 / gc_Scale));
+                       f_Spur =
+                           (gc_Scale * (f_nsLO1 - f_nsLO2)) +
+                           n * (f_LO1 % gc_Scale) - mc * (f_LO2 % gc_Scale);
+
+                       *fp = ((f_Spur - (s32) c) / (mc - n)) + 1;
+                       *fm = (((s32) d - f_Spur) / (mc - n)) + 1;
+                       return 1;
+               }
+
+               /*  Location of Zero-IF-spur to be checked  */
+               me = (n * ((f_LO1 + hgfs) / gf_Scale) +
+                     ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
+               mf = (n * ((f_LO1 + hgfs) / gf_Scale) -
+                     ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
+               if (me != mf) {
+                       f_nsLO1 = n * (f_LO1 / gf_Scale);
+                       f_nsLO2 = me * (f_LO2 / gf_Scale);
+                       f_Spur =
+                           (gf_Scale * (f_nsLO1 - f_nsLO2)) +
+                           n * (f_LO1 % gf_Scale) - me * (f_LO2 % gf_Scale);
+
+                       *fp = ((f_Spur + (s32) f) / (me - n)) + 1;
+                       *fm = (((s32) f - f_Spur) / (me - n)) + 1;
+                       return 1;
+               }
+
+               mb = (n * ((f_LO1 + hgcs) / gc_Scale) +
+                     ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
+               if (ma != mb) {
+                       f_nsLO1 = n * (f_LO1 / gc_Scale);
+                       f_nsLO2 = ma * (f_LO2 / gc_Scale);
+                       f_Spur =
+                           (gc_Scale * (f_nsLO1 - f_nsLO2)) +
+                           n * (f_LO1 % gc_Scale) - ma * (f_LO2 % gc_Scale);
+
+                       *fp = (((s32) d + f_Spur) / (ma - n)) + 1;
+                       *fm = (-(f_Spur + (s32) c) / (ma - n)) + 1;
+                       return 1;
+               }
+       }
+
+       /*  No spurs found  */
+       return 0;
+}
+
+/*
+ * MT_AvoidSpurs() - Main entry point to avoid spurs.
+ *                   Checks for existing spurs in present LO1, LO2 freqs
+ *                   and if present, chooses spur-free LO1, LO2 combination
+ *                   that tunes the same input/output frequencies.
+ */
+static u32 MT2063_AvoidSpurs(struct MT2063_AvoidSpursData_t *pAS_Info)
+{
+       u32 status = 0;
+       u32 fm, fp;             /*  restricted range on LO's        */
+       pAS_Info->bSpurAvoided = 0;
+       pAS_Info->nSpursFound = 0;
+
+       dprintk(2, "\n");
+
+       if (pAS_Info->maxH1 == 0)
+               return 0;
+
+       /*
+        * Avoid LO Generated Spurs
+        *
+        * Make sure that have no LO-related spurs within the IF output
+        * bandwidth.
+        *
+        * If there is an LO spur in this band, start at the current IF1 frequency
+        * and work out until we find a spur-free frequency or run up against the
+        * 1st IF SAW band edge.  Use temporary copies of fLO1 and fLO2 so that they
+        * will be unchanged if a spur-free setting is not found.
+        */
+       pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
+       if (pAS_Info->bSpurPresent) {
+               u32 zfIF1 = pAS_Info->f_LO1 - pAS_Info->f_in;   /*  current attempt at a 1st IF  */
+               u32 zfLO1 = pAS_Info->f_LO1;    /*  current attempt at an LO1 freq  */
+               u32 zfLO2 = pAS_Info->f_LO2;    /*  current attempt at an LO2 freq  */
+               u32 delta_IF1;
+               u32 new_IF1;
+
+               /*
+                **  Spur was found, attempt to find a spur-free 1st IF
+                */
+               do {
+                       pAS_Info->nSpursFound++;
+
+                       /*  Raise f_IF1_upper, if needed  */
+                       MT2063_AddExclZone(pAS_Info, zfIF1 - fm, zfIF1 + fp);
+
+                       /*  Choose next IF1 that is closest to f_IF1_CENTER              */
+                       new_IF1 = MT2063_ChooseFirstIF(pAS_Info);
+
+                       if (new_IF1 > zfIF1) {
+                               pAS_Info->f_LO1 += (new_IF1 - zfIF1);
+                               pAS_Info->f_LO2 += (new_IF1 - zfIF1);
+                       } else {
+                               pAS_Info->f_LO1 -= (zfIF1 - new_IF1);
+                               pAS_Info->f_LO2 -= (zfIF1 - new_IF1);
+                       }
+                       zfIF1 = new_IF1;
+
+                       if (zfIF1 > pAS_Info->f_if1_Center)
+                               delta_IF1 = zfIF1 - pAS_Info->f_if1_Center;
+                       else
+                               delta_IF1 = pAS_Info->f_if1_Center - zfIF1;
+
+                       pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
+               /*
+                *  Continue while the new 1st IF is still within the 1st IF bandwidth
+                *  and there is a spur in the band (again)
+                */
+               } while ((2 * delta_IF1 + pAS_Info->f_out_bw <= pAS_Info->f_if1_bw) && pAS_Info->bSpurPresent);
+
+               /*
+                * Use the LO-spur free values found.  If the search went all
+                * the way to the 1st IF band edge and always found spurs, just
+                * leave the original choice.  It's as "good" as any other.
+                */
+               if (pAS_Info->bSpurPresent == 1) {
+                       status |= MT2063_SPUR_PRESENT_ERR;
+                       pAS_Info->f_LO1 = zfLO1;
+                       pAS_Info->f_LO2 = zfLO2;
+               } else
+                       pAS_Info->bSpurAvoided = 1;
+       }
+
+       status |=
+           ((pAS_Info->
+             nSpursFound << MT2063_SPUR_SHIFT) & MT2063_SPUR_CNT_MASK);
+
+       return status;
+}
+
+/*
+ * Constants used by the tuning algorithm
+ */
+#define MT2063_REF_FREQ          (16000000UL)  /* Reference oscillator Frequency (in Hz) */
+#define MT2063_IF1_BW            (22000000UL)  /* The IF1 filter bandwidth (in Hz) */
+#define MT2063_TUNE_STEP_SIZE       (50000UL)  /* Tune in steps of 50 kHz */
+#define MT2063_SPUR_STEP_HZ        (250000UL)  /* Step size (in Hz) to move IF1 when avoiding spurs */
+#define MT2063_ZIF_BW             (2000000UL)  /* Zero-IF spur-free bandwidth (in Hz) */
+#define MT2063_MAX_HARMONICS_1         (15UL)  /* Highest intra-tuner LO Spur Harmonic to be avoided */
+#define MT2063_MAX_HARMONICS_2          (5UL)  /* Highest inter-tuner LO Spur Harmonic to be avoided */
+#define MT2063_MIN_LO_SEP         (1000000UL)  /* Minimum inter-tuner LO frequency separation */
+#define MT2063_LO1_FRACN_AVOID          (0UL)  /* LO1 FracN numerator avoid region (in Hz) */
+#define MT2063_LO2_FRACN_AVOID     (199999UL)  /* LO2 FracN numerator avoid region (in Hz) */
+#define MT2063_MIN_FIN_FREQ      (44000000UL)  /* Minimum input frequency (in Hz) */
+#define MT2063_MAX_FIN_FREQ    (1100000000UL)  /* Maximum input frequency (in Hz) */
+#define MT2063_MIN_FOUT_FREQ     (36000000UL)  /* Minimum output frequency (in Hz) */
+#define MT2063_MAX_FOUT_FREQ     (57000000UL)  /* Maximum output frequency (in Hz) */
+#define MT2063_MIN_DNC_FREQ    (1293000000UL)  /* Minimum LO2 frequency (in Hz) */
+#define MT2063_MAX_DNC_FREQ    (1614000000UL)  /* Maximum LO2 frequency (in Hz) */
+#define MT2063_MIN_UPC_FREQ    (1396000000UL)  /* Minimum LO1 frequency (in Hz) */
+#define MT2063_MAX_UPC_FREQ    (2750000000UL)  /* Maximum LO1 frequency (in Hz) */
+
+/*
+ *  Define the supported Part/Rev codes for the MT2063
+ */
+#define MT2063_B0       (0x9B)
+#define MT2063_B1       (0x9C)
+#define MT2063_B2       (0x9D)
+#define MT2063_B3       (0x9E)
+
+/**
+ * mt2063_lockStatus - Checks to see if LO1 and LO2 are locked
+ *
+ * @state:     struct mt2063_state pointer
+ *
+ * This function returns 0, if no lock, 1 if locked and a value < 1 if error
+ */
+static unsigned int mt2063_lockStatus(struct mt2063_state *state)
+{
+       const u32 nMaxWait = 100;       /*  wait a maximum of 100 msec   */
+       const u32 nPollRate = 2;        /*  poll status bits every 2 ms */
+       const u32 nMaxLoops = nMaxWait / nPollRate;
+       const u8 LO1LK = 0x80;
+       u8 LO2LK = 0x08;
+       u32 status;
+       u32 nDelays = 0;
+
+       dprintk(2, "\n");
+
+       /*  LO2 Lock bit was in a different place for B0 version  */
+       if (state->tuner_id == MT2063_B0)
+               LO2LK = 0x40;
+
+       do {
+               status = mt2063_read(state, MT2063_REG_LO_STATUS,
+                                    &state->reg[MT2063_REG_LO_STATUS], 1);
+
+               if (status < 0)
+                       return status;
+
+               if ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) ==
+                   (LO1LK | LO2LK)) {
+                       return TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO;
+               }
+               msleep(nPollRate);      /*  Wait between retries  */
+       } while (++nDelays < nMaxLoops);
+
+       /*
+        * Got no lock or partial lock
+        */
+       return 0;
+}
+
+/*
+ *  Constants for setting receiver modes.
+ *  (6 modes defined at this time, enumerated by mt2063_delivery_sys)
+ *  (DNC1GC & DNC2GC are the values, which are used, when the specific
+ *   DNC Output is selected, the other is always off)
+ *
+ *                enum mt2063_delivery_sys
+ * -------------+----------------------------------------------
+ * Mode 0 :     | MT2063_CABLE_QAM
+ * Mode 1 :     | MT2063_CABLE_ANALOG
+ * Mode 2 :     | MT2063_OFFAIR_COFDM
+ * Mode 3 :     | MT2063_OFFAIR_COFDM_SAWLESS
+ * Mode 4 :     | MT2063_OFFAIR_ANALOG
+ * Mode 5 :     | MT2063_OFFAIR_8VSB
+ * --------------+----------------------------------------------
+ *
+ *                |<----------   Mode  -------------->|
+ *    Reg Field   |  0  |  1  |  2  |  3  |  4  |  5  |
+ *    ------------+-----+-----+-----+-----+-----+-----+
+ *    RFAGCen     | OFF | OFF | OFF | OFF | OFF | OFF
+ *    LNARin      |   0 |   0 |   3 |   3 |  3  |  3
+ *    FIFFQen     |   1 |   1 |   1 |   1 |  1  |  1
+ *    FIFFq       |   0 |   0 |   0 |   0 |  0  |  0
+ *    DNC1gc      |   0 |   0 |   0 |   0 |  0  |  0
+ *    DNC2gc      |   0 |   0 |   0 |   0 |  0  |  0
+ *    GCU Auto    |   1 |   1 |   1 |   1 |  1  |  1
+ *    LNA max Atn |  31 |  31 |  31 |  31 | 31  | 31
+ *    LNA Target  |  44 |  43 |  43 |  43 | 43  | 43
+ *    ign  RF Ovl |   0 |   0 |   0 |   0 |  0  |  0
+ *    RF  max Atn |  31 |  31 |  31 |  31 | 31  | 31
+ *    PD1 Target  |  36 |  36 |  38 |  38 | 36  | 38
+ *    ign FIF Ovl |   0 |   0 |   0 |   0 |  0  |  0
+ *    FIF max Atn |   5 |   5 |   5 |   5 |  5  |  5
+ *    PD2 Target  |  40 |  33 |  42 |  42 | 33  | 42
+ */
+
+enum mt2063_delivery_sys {
+       MT2063_CABLE_QAM = 0,
+       MT2063_CABLE_ANALOG,
+       MT2063_OFFAIR_COFDM,
+       MT2063_OFFAIR_COFDM_SAWLESS,
+       MT2063_OFFAIR_ANALOG,
+       MT2063_OFFAIR_8VSB,
+       MT2063_NUM_RCVR_MODES
+};
+
+static const char *mt2063_mode_name[] = {
+       [MT2063_CABLE_QAM]              = "digital cable",
+       [MT2063_CABLE_ANALOG]           = "analog cable",
+       [MT2063_OFFAIR_COFDM]           = "digital offair",
+       [MT2063_OFFAIR_COFDM_SAWLESS]   = "digital offair without SAW",
+       [MT2063_OFFAIR_ANALOG]          = "analog offair",
+       [MT2063_OFFAIR_8VSB]            = "analog offair 8vsb",
+};
+
+static const u8 RFAGCEN[]      = {  0,  0,  0,  0,  0,  0 };
+static const u8 LNARIN[]       = {  0,  0,  3,  3,  3,  3 };
+static const u8 FIFFQEN[]      = {  1,  1,  1,  1,  1,  1 };
+static const u8 FIFFQ[]                = {  0,  0,  0,  0,  0,  0 };
+static const u8 DNC1GC[]       = {  0,  0,  0,  0,  0,  0 };
+static const u8 DNC2GC[]       = {  0,  0,  0,  0,  0,  0 };
+static const u8 ACLNAMAX[]     = { 31, 31, 31, 31, 31, 31 };
+static const u8 LNATGT[]       = { 44, 43, 43, 43, 43, 43 };
+static const u8 RFOVDIS[]      = {  0,  0,  0,  0,  0,  0 };
+static const u8 ACRFMAX[]      = { 31, 31, 31, 31, 31, 31 };
+static const u8 PD1TGT[]       = { 36, 36, 38, 38, 36, 38 };
+static const u8 FIFOVDIS[]     = {  0,  0,  0,  0,  0,  0 };
+static const u8 ACFIFMAX[]     = { 29, 29, 29, 29, 29, 29 };
+static const u8 PD2TGT[]       = { 40, 33, 38, 42, 30, 38 };
+
+/*
+ * mt2063_set_dnc_output_enable()
+ */
+static u32 mt2063_get_dnc_output_enable(struct mt2063_state *state,
+                                       enum MT2063_DNC_Output_Enable *pValue)
+{
+       dprintk(2, "\n");
+
+       if ((state->reg[MT2063_REG_DNC_GAIN] & 0x03) == 0x03) { /* if DNC1 is off */
+               if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03)   /* if DNC2 is off */
+                       *pValue = MT2063_DNC_NONE;
+               else
+                       *pValue = MT2063_DNC_2;
+       } else {        /* DNC1 is on */
+               if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03)   /* if DNC2 is off */
+                       *pValue = MT2063_DNC_1;
+               else
+                       *pValue = MT2063_DNC_BOTH;
+       }
+       return 0;
+}
+
+/*
+ * mt2063_set_dnc_output_enable()
+ */
+static u32 mt2063_set_dnc_output_enable(struct mt2063_state *state,
+                                       enum MT2063_DNC_Output_Enable nValue)
+{
+       u32 status = 0; /* Status to be returned        */
+       u8 val = 0;
+
+       dprintk(2, "\n");
+
+       /* selects, which DNC output is used */
+       switch (nValue) {
+       case MT2063_DNC_NONE:
+               val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03;  /* Set DNC1GC=3 */
+               if (state->reg[MT2063_REG_DNC_GAIN] !=
+                   val)
+                       status |=
+                           mt2063_setreg(state,
+                                         MT2063_REG_DNC_GAIN,
+                                         val);
+
+               val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03;  /* Set DNC2GC=3 */
+               if (state->reg[MT2063_REG_VGA_GAIN] !=
+                   val)
+                       status |=
+                           mt2063_setreg(state,
+                                         MT2063_REG_VGA_GAIN,
+                                         val);
+
+               val = (state->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */
+               if (state->reg[MT2063_REG_RSVD_20] !=
+                   val)
+                       status |=
+                           mt2063_setreg(state,
+                                         MT2063_REG_RSVD_20,
+                                         val);
+
+               break;
+       case MT2063_DNC_1:
+               val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03);     /* Set DNC1GC=x */
+               if (state->reg[MT2063_REG_DNC_GAIN] !=
+                   val)
+                       status |=
+                           mt2063_setreg(state,
+                                         MT2063_REG_DNC_GAIN,
+                                         val);
+
+               val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03;  /* Set DNC2GC=3 */
+               if (state->reg[MT2063_REG_VGA_GAIN] !=
+                   val)
+                       status |=
+                           mt2063_setreg(state,
+                                         MT2063_REG_VGA_GAIN,
+                                         val);
+
+               val = (state->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */
+               if (state->reg[MT2063_REG_RSVD_20] !=
+                   val)
+                       status |=
+                           mt2063_setreg(state,
+                                         MT2063_REG_RSVD_20,
+                                         val);
+
+               break;
+       case MT2063_DNC_2:
+               val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03;  /* Set DNC1GC=3 */
+               if (state->reg[MT2063_REG_DNC_GAIN] !=
+                   val)
+                       status |=
+                           mt2063_setreg(state,
+                                         MT2063_REG_DNC_GAIN,
+                                         val);
+
+               val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03);     /* Set DNC2GC=x */
+               if (state->reg[MT2063_REG_VGA_GAIN] !=
+                   val)
+                       status |=
+                           mt2063_setreg(state,
+                                         MT2063_REG_VGA_GAIN,
+                                         val);
+
+               val = (state->reg[MT2063_REG_RSVD_20] | 0x40);  /* Set PD2MUX=1 */
+               if (state->reg[MT2063_REG_RSVD_20] !=
+                   val)
+                       status |=
+                           mt2063_setreg(state,
+                                         MT2063_REG_RSVD_20,
+                                         val);
+
+               break;
+       case MT2063_DNC_BOTH:
+               val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03);     /* Set DNC1GC=x */
+               if (state->reg[MT2063_REG_DNC_GAIN] !=
+                   val)
+                       status |=
+                           mt2063_setreg(state,
+                                         MT2063_REG_DNC_GAIN,
+                                         val);
+
+               val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03);     /* Set DNC2GC=x */
+               if (state->reg[MT2063_REG_VGA_GAIN] !=
+                   val)
+                       status |=
+                           mt2063_setreg(state,
+                                         MT2063_REG_VGA_GAIN,
+                                         val);
+
+               val = (state->reg[MT2063_REG_RSVD_20] | 0x40);  /* Set PD2MUX=1 */
+               if (state->reg[MT2063_REG_RSVD_20] !=
+                   val)
+                       status |=
+                           mt2063_setreg(state,
+                                         MT2063_REG_RSVD_20,
+                                         val);
+
+               break;
+       default:
+               break;
+       }
+
+       return status;
+}
+
+/*
+ * MT2063_SetReceiverMode() - Set the MT2063 receiver mode, according with
+ *                           the selected enum mt2063_delivery_sys type.
+ *
+ *  (DNC1GC & DNC2GC are the values, which are used, when the specific
+ *   DNC Output is selected, the other is always off)
+ *
+ * @state:     ptr to mt2063_state structure
+ * @Mode:      desired reciever delivery system
+ *
+ * Note: Register cache must be valid for it to work
+ */
+
+static u32 MT2063_SetReceiverMode(struct mt2063_state *state,
+                                 enum mt2063_delivery_sys Mode)
+{
+       u32 status = 0; /* Status to be returned        */
+       u8 val;
+       u32 longval;
+
+       dprintk(2, "\n");
+
+       if (Mode >= MT2063_NUM_RCVR_MODES)
+               status = -ERANGE;
+
+       /* RFAGCen */
+       if (status >= 0) {
+               val =
+                   (state->
+                    reg[MT2063_REG_PD1_TGT] & (u8) ~0x40) | (RFAGCEN[Mode]
+                                                                  ? 0x40 :
+                                                                  0x00);
+               if (state->reg[MT2063_REG_PD1_TGT] != val)
+                       status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
+       }
+
+       /* LNARin */
+       if (status >= 0) {
+               u8 val = (state->reg[MT2063_REG_CTRL_2C] & (u8) ~0x03) |
+                        (LNARIN[Mode] & 0x03);
+               if (state->reg[MT2063_REG_CTRL_2C] != val)
+                       status |= mt2063_setreg(state, MT2063_REG_CTRL_2C, val);
+       }
+
+       /* FIFFQEN and FIFFQ */
+       if (status >= 0) {
+               val =
+                   (state->
+                    reg[MT2063_REG_FIFF_CTRL2] & (u8) ~0xF0) |
+                   (FIFFQEN[Mode] << 7) | (FIFFQ[Mode] << 4);
+               if (state->reg[MT2063_REG_FIFF_CTRL2] != val) {
+                       status |=
+                           mt2063_setreg(state, MT2063_REG_FIFF_CTRL2, val);
+                       /* trigger FIFF calibration, needed after changing FIFFQ */
+                       val =
+                           (state->reg[MT2063_REG_FIFF_CTRL] | (u8) 0x01);
+                       status |=
+                           mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
+                       val =
+                           (state->
+                            reg[MT2063_REG_FIFF_CTRL] & (u8) ~0x01);
+                       status |=
+                           mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
+               }
+       }
+
+       /* DNC1GC & DNC2GC */
+       status |= mt2063_get_dnc_output_enable(state, &longval);
+       status |= mt2063_set_dnc_output_enable(state, longval);
+
+       /* acLNAmax */
+       if (status >= 0) {
+               u8 val = (state->reg[MT2063_REG_LNA_OV] & (u8) ~0x1F) |
+                        (ACLNAMAX[Mode] & 0x1F);
+               if (state->reg[MT2063_REG_LNA_OV] != val)
+                       status |= mt2063_setreg(state, MT2063_REG_LNA_OV, val);
+       }
+
+       /* LNATGT */
+       if (status >= 0) {
+               u8 val = (state->reg[MT2063_REG_LNA_TGT] & (u8) ~0x3F) |
+                        (LNATGT[Mode] & 0x3F);
+               if (state->reg[MT2063_REG_LNA_TGT] != val)
+                       status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
+       }
+
+       /* ACRF */
+       if (status >= 0) {
+               u8 val = (state->reg[MT2063_REG_RF_OV] & (u8) ~0x1F) |
+                        (ACRFMAX[Mode] & 0x1F);
+               if (state->reg[MT2063_REG_RF_OV] != val)
+                       status |= mt2063_setreg(state, MT2063_REG_RF_OV, val);
+       }
+
+       /* PD1TGT */
+       if (status >= 0) {
+               u8 val = (state->reg[MT2063_REG_PD1_TGT] & (u8) ~0x3F) |
+                        (PD1TGT[Mode] & 0x3F);
+               if (state->reg[MT2063_REG_PD1_TGT] != val)
+                       status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
+       }
+
+       /* FIFATN */
+       if (status >= 0) {
+               u8 val = ACFIFMAX[Mode];
+               if (state->reg[MT2063_REG_PART_REV] != MT2063_B3 && val > 5)
+                       val = 5;
+               val = (state->reg[MT2063_REG_FIF_OV] & (u8) ~0x1F) |
+                     (val & 0x1F);
+               if (state->reg[MT2063_REG_FIF_OV] != val)
+                       status |= mt2063_setreg(state, MT2063_REG_FIF_OV, val);
+       }
+
+       /* PD2TGT */
+       if (status >= 0) {
+               u8 val = (state->reg[MT2063_REG_PD2_TGT] & (u8) ~0x3F) |
+                   (PD2TGT[Mode] & 0x3F);
+               if (state->reg[MT2063_REG_PD2_TGT] != val)
+                       status |= mt2063_setreg(state, MT2063_REG_PD2_TGT, val);
+       }
+
+       /* Ignore ATN Overload */
+       if (status >= 0) {
+               val = (state->reg[MT2063_REG_LNA_TGT] & (u8) ~0x80) |
+                     (RFOVDIS[Mode] ? 0x80 : 0x00);
+               if (state->reg[MT2063_REG_LNA_TGT] != val)
+                       status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
+       }
+
+       /* Ignore FIF Overload */
+       if (status >= 0) {
+               val = (state->reg[MT2063_REG_PD1_TGT] & (u8) ~0x80) |
+                     (FIFOVDIS[Mode] ? 0x80 : 0x00);
+               if (state->reg[MT2063_REG_PD1_TGT] != val)
+                       status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
+       }
+
+       if (status >= 0) {
+               state->rcvr_mode = Mode;
+               dprintk(1, "mt2063 mode changed to %s\n",
+                       mt2063_mode_name[state->rcvr_mode]);
+       }
+
+       return status;
+}
+
+/*
+ * MT2063_ClearPowerMaskBits () - Clears the power-down mask bits for various
+ *                               sections of the MT2063
+ *
+ * @Bits:              Mask bits to be cleared.
+ *
+ * See definition of MT2063_Mask_Bits type for description
+ * of each of the power bits.
+ */
+static u32 MT2063_ClearPowerMaskBits(struct mt2063_state *state,
+                                    enum MT2063_Mask_Bits Bits)
+{
+       u32 status = 0;
+
+       dprintk(2, "\n");
+       Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD);   /* Only valid bits for this tuner */
+       if ((Bits & 0xFF00) != 0) {
+               state->reg[MT2063_REG_PWR_2] &= ~(u8) (Bits >> 8);
+               status |=
+                   mt2063_write(state,
+                                   MT2063_REG_PWR_2,
+                                   &state->reg[MT2063_REG_PWR_2], 1);
+       }
+       if ((Bits & 0xFF) != 0) {
+               state->reg[MT2063_REG_PWR_1] &= ~(u8) (Bits & 0xFF);
+               status |=
+                   mt2063_write(state,
+                                   MT2063_REG_PWR_1,
+                                   &state->reg[MT2063_REG_PWR_1], 1);
+       }
+
+       return status;
+}
+
+/*
+ * MT2063_SoftwareShutdown() - Enables or disables software shutdown function.
+ *                            When Shutdown is 1, any section whose power
+ *                            mask is set will be shutdown.
+ */
+static u32 MT2063_SoftwareShutdown(struct mt2063_state *state, u8 Shutdown)
+{
+       u32 status;
+
+       dprintk(2, "\n");
+       if (Shutdown == 1)
+               state->reg[MT2063_REG_PWR_1] |= 0x04;
+       else
+               state->reg[MT2063_REG_PWR_1] &= ~0x04;
+
+       status = mt2063_write(state,
+                           MT2063_REG_PWR_1,
+                           &state->reg[MT2063_REG_PWR_1], 1);
+
+       if (Shutdown != 1) {
+               state->reg[MT2063_REG_BYP_CTRL] =
+                   (state->reg[MT2063_REG_BYP_CTRL] & 0x9F) | 0x40;
+               status |=
+                   mt2063_write(state,
+                                   MT2063_REG_BYP_CTRL,
+                                   &state->reg[MT2063_REG_BYP_CTRL],
+                                   1);
+               state->reg[MT2063_REG_BYP_CTRL] =
+                   (state->reg[MT2063_REG_BYP_CTRL] & 0x9F);
+               status |=
+                   mt2063_write(state,
+                                   MT2063_REG_BYP_CTRL,
+                                   &state->reg[MT2063_REG_BYP_CTRL],
+                                   1);
+       }
+
+       return status;
+}
+
+static u32 MT2063_Round_fLO(u32 f_LO, u32 f_LO_Step, u32 f_ref)
+{
+       return f_ref * (f_LO / f_ref)
+           + f_LO_Step * (((f_LO % f_ref) + (f_LO_Step / 2)) / f_LO_Step);
+}
+
+/**
+ * fLO_FractionalTerm() - Calculates the portion contributed by FracN / denom.
+ *                        This function preserves maximum precision without
+ *                        risk of overflow.  It accurately calculates
+ *                        f_ref * num / denom to within 1 HZ with fixed math.
+ *
+ * @num :      Fractional portion of the multiplier
+ * @denom:     denominator portion of the ratio
+ * @f_Ref:     SRO frequency.
+ *
+ * This calculation handles f_ref as two separate 14-bit fields.
+ * Therefore, a maximum value of 2^28-1 may safely be used for f_ref.
+ * This is the genesis of the magic number "14" and the magic mask value of
+ * 0x03FFF.
+ *
+ * This routine successfully handles denom values up to and including 2^18.
+ *  Returns:        f_ref * num / denom
+ */
+static u32 MT2063_fLO_FractionalTerm(u32 f_ref, u32 num, u32 denom)
+{
+       u32 t1 = (f_ref >> 14) * num;
+       u32 term1 = t1 / denom;
+       u32 loss = t1 % denom;
+       u32 term2 =
+           (((f_ref & 0x00003FFF) * num + (loss << 14)) + (denom / 2)) / denom;
+       return (term1 << 14) + term2;
+}
+
+/*
+ * CalcLO1Mult()- Calculates Integer divider value and the numerator
+ *                value for a FracN PLL.
+ *
+ *                This function assumes that the f_LO and f_Ref are
+ *                evenly divisible by f_LO_Step.
+ *
+ * @Div:       OUTPUT: Whole number portion of the multiplier
+ * @FracN:     OUTPUT: Fractional portion of the multiplier
+ * @f_LO:      desired LO frequency.
+ * @f_LO_Step: Minimum step size for the LO (in Hz).
+ * @f_Ref:     SRO frequency.
+ * @f_Avoid:   Range of PLL frequencies to avoid near integer multiples
+ *             of f_Ref (in Hz).
+ *
+ * Returns:        Recalculated LO frequency.
+ */
+static u32 MT2063_CalcLO1Mult(u32 *Div,
+                             u32 *FracN,
+                             u32 f_LO,
+                             u32 f_LO_Step, u32 f_Ref)
+{
+       /*  Calculate the whole number portion of the divider */
+       *Div = f_LO / f_Ref;
+
+       /*  Calculate the numerator value (round to nearest f_LO_Step) */
+       *FracN =
+           (64 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
+            (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
+
+       return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN, 64);
+}
+
+/**
+ * CalcLO2Mult() - Calculates Integer divider value and the numerator
+ *                 value for a FracN PLL.
+ *
+ *                  This function assumes that the f_LO and f_Ref are
+ *                  evenly divisible by f_LO_Step.
+ *
+ * @Div:       OUTPUT: Whole number portion of the multiplier
+ * @FracN:     OUTPUT: Fractional portion of the multiplier
+ * @f_LO:      desired LO frequency.
+ * @f_LO_Step: Minimum step size for the LO (in Hz).
+ * @f_Ref:     SRO frequency.
+ * @f_Avoid:   Range of PLL frequencies to avoid near
+ *             integer multiples of f_Ref (in Hz).
+ *
+ * Returns: Recalculated LO frequency.
+ */
+static u32 MT2063_CalcLO2Mult(u32 *Div,
+                             u32 *FracN,
+                             u32 f_LO,
+                             u32 f_LO_Step, u32 f_Ref)
+{
+       /*  Calculate the whole number portion of the divider */
+       *Div = f_LO / f_Ref;
+
+       /*  Calculate the numerator value (round to nearest f_LO_Step) */
+       *FracN =
+           (8191 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
+            (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
+
+       return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN,
+                                                           8191);
+}
+
+/*
+ * FindClearTuneFilter() - Calculate the corrrect ClearTune filter to be
+ *                        used for a given input frequency.
+ *
+ * @state:     ptr to tuner data structure
+ * @f_in:      RF input center frequency (in Hz).
+ *
+ * Returns: ClearTune filter number (0-31)
+ */
+static u32 FindClearTuneFilter(struct mt2063_state *state, u32 f_in)
+{
+       u32 RFBand;
+       u32 idx;                /*  index loop                      */
+
+       /*
+        **  Find RF Band setting
+        */
+       RFBand = 31;            /*  def when f_in > all    */
+       for (idx = 0; idx < 31; ++idx) {
+               if (state->CTFiltMax[idx] >= f_in) {
+                       RFBand = idx;
+                       break;
+               }
+       }
+       return RFBand;
+}
+
+/*
+ * MT2063_Tune() - Change the tuner's tuned frequency to RFin.
+ */
+static u32 MT2063_Tune(struct mt2063_state *state, u32 f_in)
+{                              /* RF input center frequency   */
+
+       u32 status = 0;
+       u32 LO1;                /*  1st LO register value           */
+       u32 Num1;               /*  Numerator for LO1 reg. value    */
+       u32 f_IF1;              /*  1st IF requested                */
+       u32 LO2;                /*  2nd LO register value           */
+       u32 Num2;               /*  Numerator for LO2 reg. value    */
+       u32 ofLO1, ofLO2;       /*  last time's LO frequencies      */
+       u8 fiffc = 0x80;        /*  FIFF center freq from tuner     */
+       u32 fiffof;             /*  Offset from FIFF center freq    */
+       const u8 LO1LK = 0x80;  /*  Mask for LO1 Lock bit           */
+       u8 LO2LK = 0x08;        /*  Mask for LO2 Lock bit           */
+       u8 val;
+       u32 RFBand;
+
+       dprintk(2, "\n");
+       /*  Check the input and output frequency ranges                   */
+       if ((f_in < MT2063_MIN_FIN_FREQ) || (f_in > MT2063_MAX_FIN_FREQ))
+               return -EINVAL;
+
+       if ((state->AS_Data.f_out < MT2063_MIN_FOUT_FREQ)
+           || (state->AS_Data.f_out > MT2063_MAX_FOUT_FREQ))
+               return -EINVAL;
+
+       /*
+        * Save original LO1 and LO2 register values
+        */
+       ofLO1 = state->AS_Data.f_LO1;
+       ofLO2 = state->AS_Data.f_LO2; 
+
+       /*
+        * Find and set RF Band setting
+        */
+       if (state->ctfilt_sw == 1) {
+               val = (state->reg[MT2063_REG_CTUNE_CTRL] | 0x08);
+               if (state->reg[MT2063_REG_CTUNE_CTRL] != val) {
+                       status |=
+                           mt2063_setreg(state, MT2063_REG_CTUNE_CTRL, val);
+               }
+               val = state->reg[MT2063_REG_CTUNE_OV];
+               RFBand = FindClearTuneFilter(state, f_in);
+               state->reg[MT2063_REG_CTUNE_OV] =
+                   (u8) ((state->reg[MT2063_REG_CTUNE_OV] & ~0x1F)
+                             | RFBand);
+               if (state->reg[MT2063_REG_CTUNE_OV] != val) {
+                       status |=
+                           mt2063_setreg(state, MT2063_REG_CTUNE_OV, val);
+               }
+       }
+
+       /*
+        * Read the FIFF Center Frequency from the tuner
+        */
+       if (status >= 0) {
+               status |=
+                   mt2063_read(state,
+                                  MT2063_REG_FIFFC,
+                                  &state->reg[MT2063_REG_FIFFC], 1);
+               fiffc = state->reg[MT2063_REG_FIFFC];
+       }
+       /*
+        * Assign in the requested values
+        */
+       state->AS_Data.f_in = f_in;
+       /*  Request a 1st IF such that LO1 is on a step size */
+       state->AS_Data.f_if1_Request =
+           MT2063_Round_fLO(state->AS_Data.f_if1_Request + f_in,
+                            state->AS_Data.f_LO1_Step,
+                            state->AS_Data.f_ref) - f_in;
+
+       /*
+        * Calculate frequency settings.  f_IF1_FREQ + f_in is the
+        * desired LO1 frequency
+        */
+       MT2063_ResetExclZones(&state->AS_Data);
+
+       f_IF1 = MT2063_ChooseFirstIF(&state->AS_Data);
+
+       state->AS_Data.f_LO1 =
+           MT2063_Round_fLO(f_IF1 + f_in, state->AS_Data.f_LO1_Step,
+                            state->AS_Data.f_ref);
+
+       state->AS_Data.f_LO2 =
+           MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
+                            state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
+
+       /*
+        * Check for any LO spurs in the output bandwidth and adjust
+        * the LO settings to avoid them if needed
+        */
+       status |= MT2063_AvoidSpurs(&state->AS_Data);
+       /*
+        * MT_AvoidSpurs spurs may have changed the LO1 & LO2 values.
+        * Recalculate the LO frequencies and the values to be placed
+        * in the tuning registers.
+        */
+       state->AS_Data.f_LO1 =
+           MT2063_CalcLO1Mult(&LO1, &Num1, state->AS_Data.f_LO1,
+                              state->AS_Data.f_LO1_Step, state->AS_Data.f_ref);
+       state->AS_Data.f_LO2 =
+           MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
+                            state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
+       state->AS_Data.f_LO2 =
+           MT2063_CalcLO2Mult(&LO2, &Num2, state->AS_Data.f_LO2,
+                              state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
+
+       /*
+        *  Check the upconverter and downconverter frequency ranges
+        */
+       if ((state->AS_Data.f_LO1 < MT2063_MIN_UPC_FREQ)
+           || (state->AS_Data.f_LO1 > MT2063_MAX_UPC_FREQ))
+               status |= MT2063_UPC_RANGE;
+       if ((state->AS_Data.f_LO2 < MT2063_MIN_DNC_FREQ)
+           || (state->AS_Data.f_LO2 > MT2063_MAX_DNC_FREQ))
+               status |= MT2063_DNC_RANGE;
+       /*  LO2 Lock bit was in a different place for B0 version  */
+       if (state->tuner_id == MT2063_B0)
+               LO2LK = 0x40;
+
+       /*
+        *  If we have the same LO frequencies and we're already locked,
+        *  then skip re-programming the LO registers.
+        */
+       if ((ofLO1 != state->AS_Data.f_LO1)
+           || (ofLO2 != state->AS_Data.f_LO2)
+           || ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) !=
+               (LO1LK | LO2LK))) {
+               /*
+                * Calculate the FIFFOF register value
+                *
+                *           IF1_Actual
+                * FIFFOF = ------------ - 8 * FIFFC - 4992
+                *            f_ref/64
+                */
+               fiffof =
+                   (state->AS_Data.f_LO1 -
+                    f_in) / (state->AS_Data.f_ref / 64) - 8 * (u32) fiffc -
+                   4992;
+               if (fiffof > 0xFF)
+                       fiffof = 0xFF;
+
+               /*
+                * Place all of the calculated values into the local tuner
+                * register fields.
+                */
+               if (status >= 0) {
+                       state->reg[MT2063_REG_LO1CQ_1] = (u8) (LO1 & 0xFF);     /* DIV1q */
+                       state->reg[MT2063_REG_LO1CQ_2] = (u8) (Num1 & 0x3F);    /* NUM1q */
+                       state->reg[MT2063_REG_LO2CQ_1] = (u8) (((LO2 & 0x7F) << 1)      /* DIV2q */
+                                                                  |(Num2 >> 12));      /* NUM2q (hi) */
+                       state->reg[MT2063_REG_LO2CQ_2] = (u8) ((Num2 & 0x0FF0) >> 4);   /* NUM2q (mid) */
+                       state->reg[MT2063_REG_LO2CQ_3] = (u8) (0xE0 | (Num2 & 0x000F)); /* NUM2q (lo) */
+
+                       /*
+                        * Now write out the computed register values
+                        * IMPORTANT: There is a required order for writing
+                        *            (0x05 must follow all the others).
+                        */
+                       status |= mt2063_write(state, MT2063_REG_LO1CQ_1, &state->reg[MT2063_REG_LO1CQ_1], 5);  /* 0x01 - 0x05 */
+                       if (state->tuner_id == MT2063_B0) {
+                               /* Re-write the one-shot bits to trigger the tune operation */
+                               status |= mt2063_write(state, MT2063_REG_LO2CQ_3, &state->reg[MT2063_REG_LO2CQ_3], 1);  /* 0x05 */
+                       }
+                       /* Write out the FIFF offset only if it's changing */
+                       if (state->reg[MT2063_REG_FIFF_OFFSET] !=
+                           (u8) fiffof) {
+                               state->reg[MT2063_REG_FIFF_OFFSET] =
+                                   (u8) fiffof;
+                               status |=
+                                   mt2063_write(state,
+                                                   MT2063_REG_FIFF_OFFSET,
+                                                   &state->
+                                                   reg[MT2063_REG_FIFF_OFFSET],
+                                                   1);
+                       }
+               }
+
+               /*
+                * Check for LO's locking
+                */
+
+               if (status < 0)
+                       return status;
+
+               status = mt2063_lockStatus(state);
+               if (status < 0)
+                       return status;
+               if (!status)
+                       return -EINVAL;         /* Couldn't lock */
+
+               /*
+                * If we locked OK, assign calculated data to mt2063_state structure
+                */
+               state->f_IF1_actual = state->AS_Data.f_LO1 - f_in;
+       }
+
+       return status;
+}
+
+static const u8 MT2063B0_defaults[] = {
+       /* Reg,  Value */
+       0x19, 0x05,
+       0x1B, 0x1D,
+       0x1C, 0x1F,
+       0x1D, 0x0F,
+       0x1E, 0x3F,
+       0x1F, 0x0F,
+       0x20, 0x3F,
+       0x22, 0x21,
+       0x23, 0x3F,
+       0x24, 0x20,
+       0x25, 0x3F,
+       0x27, 0xEE,
+       0x2C, 0x27,     /*  bit at 0x20 is cleared below  */
+       0x30, 0x03,
+       0x2C, 0x07,     /*  bit at 0x20 is cleared here   */
+       0x2D, 0x87,
+       0x2E, 0xAA,
+       0x28, 0xE1,     /*  Set the FIFCrst bit here      */
+       0x28, 0xE0,     /*  Clear the FIFCrst bit here    */
+       0x00
+};
+
+/* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
+static const u8 MT2063B1_defaults[] = {
+       /* Reg,  Value */
+       0x05, 0xF0,
+       0x11, 0x10,     /* New Enable AFCsd */
+       0x19, 0x05,
+       0x1A, 0x6C,
+       0x1B, 0x24,
+       0x1C, 0x28,
+       0x1D, 0x8F,
+       0x1E, 0x14,
+       0x1F, 0x8F,
+       0x20, 0x57,
+       0x22, 0x21,     /* New - ver 1.03 */
+       0x23, 0x3C,     /* New - ver 1.10 */
+       0x24, 0x20,     /* New - ver 1.03 */
+       0x2C, 0x24,     /*  bit at 0x20 is cleared below  */
+       0x2D, 0x87,     /*  FIFFQ=0  */
+       0x2F, 0xF3,
+       0x30, 0x0C,     /* New - ver 1.11 */
+       0x31, 0x1B,     /* New - ver 1.11 */
+       0x2C, 0x04,     /*  bit at 0x20 is cleared here  */
+       0x28, 0xE1,     /*  Set the FIFCrst bit here      */
+       0x28, 0xE0,     /*  Clear the FIFCrst bit here    */
+       0x00
+};
+
+/* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
+static const u8 MT2063B3_defaults[] = {
+       /* Reg,  Value */
+       0x05, 0xF0,
+       0x19, 0x3D,
+       0x2C, 0x24,     /*  bit at 0x20 is cleared below  */
+       0x2C, 0x04,     /*  bit at 0x20 is cleared here  */
+       0x28, 0xE1,     /*  Set the FIFCrst bit here      */
+       0x28, 0xE0,     /*  Clear the FIFCrst bit here    */
+       0x00
+};
+
+static int mt2063_init(struct dvb_frontend *fe)
+{
+       u32 status;
+       struct mt2063_state *state = fe->tuner_priv;
+       u8 all_resets = 0xF0;   /* reset/load bits */
+       const u8 *def = NULL;
+       char *step;
+       u32 FCRUN;
+       s32 maxReads;
+       u32 fcu_osc;
+       u32 i;
+
+       dprintk(2, "\n");
+
+       state->rcvr_mode = MT2063_CABLE_QAM;
+
+       /*  Read the Part/Rev code from the tuner */
+       status = mt2063_read(state, MT2063_REG_PART_REV,
+                            &state->reg[MT2063_REG_PART_REV], 1);
+       if (status < 0) {
+               printk(KERN_ERR "Can't read mt2063 part ID\n");
+               return status;
+       }
+
+       /* Check the part/rev code */
+       switch (state->reg[MT2063_REG_PART_REV]) {
+       case MT2063_B0:
+               step = "B0";
+               break;
+       case MT2063_B1:
+               step = "B1";
+               break;
+       case MT2063_B2:
+               step = "B2";
+               break;
+       case MT2063_B3:
+               step = "B3";
+               break;
+       default:
+               printk(KERN_ERR "mt2063: Unknown mt2063 device ID (0x%02x)\n",
+                      state->reg[MT2063_REG_PART_REV]);
+               return -ENODEV; /*  Wrong tuner Part/Rev code */
+       }
+
+       /*  Check the 2nd byte of the Part/Rev code from the tuner */
+       status = mt2063_read(state, MT2063_REG_RSVD_3B,
+                            &state->reg[MT2063_REG_RSVD_3B], 1);
+
+       /* b7 != 0 ==> NOT MT2063 */
+       if (status < 0 || ((state->reg[MT2063_REG_RSVD_3B] & 0x80) != 0x00)) {
+               printk(KERN_ERR "mt2063: Unknown part ID (0x%02x%02x)\n",
+                      state->reg[MT2063_REG_PART_REV],
+                      state->reg[MT2063_REG_RSVD_3B]);
+               return -ENODEV; /*  Wrong tuner Part/Rev code */
+       }
+
+       printk(KERN_INFO "mt2063: detected a mt2063 %s\n", step);
+
+       /*  Reset the tuner  */
+       status = mt2063_write(state, MT2063_REG_LO2CQ_3, &all_resets, 1);
+       if (status < 0)
+               return status;
+
+       /* change all of the default values that vary from the HW reset values */
+       /*  def = (state->reg[PART_REV] == MT2063_B0) ? MT2063B0_defaults : MT2063B1_defaults; */
+       switch (state->reg[MT2063_REG_PART_REV]) {
+       case MT2063_B3:
+               def = MT2063B3_defaults;
+               break;
+
+       case MT2063_B1:
+               def = MT2063B1_defaults;
+               break;
+
+       case MT2063_B0:
+               def = MT2063B0_defaults;
+               break;
+
+       default:
+               return -ENODEV;
+               break;
+       }
+
+       while (status >= 0 && *def) {
+               u8 reg = *def++;
+               u8 val = *def++;
+               status = mt2063_write(state, reg, &val, 1);
+       }
+       if (status < 0)
+               return status;
+
+       /*  Wait for FIFF location to complete.  */
+       FCRUN = 1;
+       maxReads = 10;
+       while (status >= 0 && (FCRUN != 0) && (maxReads-- > 0)) {
+               msleep(2);
+               status = mt2063_read(state,
+                                        MT2063_REG_XO_STATUS,
+                                        &state->
+                                        reg[MT2063_REG_XO_STATUS], 1);
+               FCRUN = (state->reg[MT2063_REG_XO_STATUS] & 0x40) >> 6;
+       }
+
+       if (FCRUN != 0 || status < 0)
+               return -ENODEV;
+
+       status = mt2063_read(state,
+                          MT2063_REG_FIFFC,
+                          &state->reg[MT2063_REG_FIFFC], 1);
+       if (status < 0)
+               return status;
+
+       /* Read back all the registers from the tuner */
+       status = mt2063_read(state,
+                               MT2063_REG_PART_REV,
+                               state->reg, MT2063_REG_END_REGS);
+       if (status < 0)
+               return status;
+
+       /*  Initialize the tuner state.  */
+       state->tuner_id = state->reg[MT2063_REG_PART_REV];
+       state->AS_Data.f_ref = MT2063_REF_FREQ;
+       state->AS_Data.f_if1_Center = (state->AS_Data.f_ref / 8) *
+                                     ((u32) state->reg[MT2063_REG_FIFFC] + 640);
+       state->AS_Data.f_if1_bw = MT2063_IF1_BW;
+       state->AS_Data.f_out = 43750000UL;
+       state->AS_Data.f_out_bw = 6750000UL;
+       state->AS_Data.f_zif_bw = MT2063_ZIF_BW;
+       state->AS_Data.f_LO1_Step = state->AS_Data.f_ref / 64;
+       state->AS_Data.f_LO2_Step = MT2063_TUNE_STEP_SIZE;
+       state->AS_Data.maxH1 = MT2063_MAX_HARMONICS_1;
+       state->AS_Data.maxH2 = MT2063_MAX_HARMONICS_2;
+       state->AS_Data.f_min_LO_Separation = MT2063_MIN_LO_SEP;
+       state->AS_Data.f_if1_Request = state->AS_Data.f_if1_Center;
+       state->AS_Data.f_LO1 = 2181000000UL;
+       state->AS_Data.f_LO2 = 1486249786UL;
+       state->f_IF1_actual = state->AS_Data.f_if1_Center;
+       state->AS_Data.f_in = state->AS_Data.f_LO1 - state->f_IF1_actual;
+       state->AS_Data.f_LO1_FracN_Avoid = MT2063_LO1_FRACN_AVOID;
+       state->AS_Data.f_LO2_FracN_Avoid = MT2063_LO2_FRACN_AVOID;
+       state->num_regs = MT2063_REG_END_REGS;
+       state->AS_Data.avoidDECT = MT2063_AVOID_BOTH;
+       state->ctfilt_sw = 0;
+
+       state->CTFiltMax[0] = 69230000;
+       state->CTFiltMax[1] = 105770000;
+       state->CTFiltMax[2] = 140350000;
+       state->CTFiltMax[3] = 177110000;
+       state->CTFiltMax[4] = 212860000;
+       state->CTFiltMax[5] = 241130000;
+       state->CTFiltMax[6] = 274370000;
+       state->CTFiltMax[7] = 309820000;
+       state->CTFiltMax[8] = 342450000;
+       state->CTFiltMax[9] = 378870000;
+       state->CTFiltMax[10] = 416210000;
+       state->CTFiltMax[11] = 456500000;
+       state->CTFiltMax[12] = 495790000;
+       state->CTFiltMax[13] = 534530000;
+       state->CTFiltMax[14] = 572610000;
+       state->CTFiltMax[15] = 598970000;
+       state->CTFiltMax[16] = 635910000;
+       state->CTFiltMax[17] = 672130000;
+       state->CTFiltMax[18] = 714840000;
+       state->CTFiltMax[19] = 739660000;
+       state->CTFiltMax[20] = 770410000;
+       state->CTFiltMax[21] = 814660000;
+       state->CTFiltMax[22] = 846950000;
+       state->CTFiltMax[23] = 867820000;
+       state->CTFiltMax[24] = 915980000;
+       state->CTFiltMax[25] = 947450000;
+       state->CTFiltMax[26] = 983110000;
+       state->CTFiltMax[27] = 1021630000;
+       state->CTFiltMax[28] = 1061870000;
+       state->CTFiltMax[29] = 1098330000;
+       state->CTFiltMax[30] = 1138990000;
+
+       /*
+        **   Fetch the FCU osc value and use it and the fRef value to
+        **   scale all of the Band Max values
+        */
+
+       state->reg[MT2063_REG_CTUNE_CTRL] = 0x0A;
+       status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
+                             &state->reg[MT2063_REG_CTUNE_CTRL], 1);
+       if (status < 0)
+               return status;
+
+       /*  Read the ClearTune filter calibration value  */
+       status = mt2063_read(state, MT2063_REG_FIFFC,
+                            &state->reg[MT2063_REG_FIFFC], 1);
+       if (status < 0)
+               return status;
+
+       fcu_osc = state->reg[MT2063_REG_FIFFC];
+
+       state->reg[MT2063_REG_CTUNE_CTRL] = 0x00;
+       status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
+                             &state->reg[MT2063_REG_CTUNE_CTRL], 1);
+       if (status < 0)
+               return status;
+
+       /*  Adjust each of the values in the ClearTune filter cross-over table  */
+       for (i = 0; i < 31; i++)
+               state->CTFiltMax[i] = (state->CTFiltMax[i] / 768) * (fcu_osc + 640);
+
+       status = MT2063_SoftwareShutdown(state, 1);
+       if (status < 0)
+               return status;
+       status = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
+       if (status < 0)
+               return status;
+
+       state->init = true;
+
+       return 0;
+}
+
+static int mt2063_get_status(struct dvb_frontend *fe, u32 *tuner_status)
+{
+       struct mt2063_state *state = fe->tuner_priv;
+       int status;
+
+       dprintk(2, "\n");
+
+       if (!state->init)
+               return -ENODEV;
+
+       *tuner_status = 0;
+       status = mt2063_lockStatus(state);
+       if (status < 0)
+               return status;
+       if (status)
+               *tuner_status = TUNER_STATUS_LOCKED;
+
+       dprintk(1, "Tuner status: %d", *tuner_status);
+
+       return 0;
+}
+
+static int mt2063_release(struct dvb_frontend *fe)
+{
+       struct mt2063_state *state = fe->tuner_priv;
+
+       dprintk(2, "\n");
+
+       fe->tuner_priv = NULL;
+       kfree(state);
+
+       return 0;
+}
+
+static int mt2063_set_analog_params(struct dvb_frontend *fe,
+                                   struct analog_parameters *params)
+{
+       struct mt2063_state *state = fe->tuner_priv;
+       s32 pict_car;
+       s32 pict2chanb_vsb;
+       s32 ch_bw;
+       s32 if_mid;
+       s32 rcvr_mode;
+       int status;
+
+       dprintk(2, "\n");
+
+       if (!state->init) {
+               status = mt2063_init(fe);
+               if (status < 0)
+                       return status;
+       }
+
+       switch (params->mode) {
+       case V4L2_TUNER_RADIO:
+               pict_car = 38900000;
+               ch_bw = 8000000;
+               pict2chanb_vsb = -(ch_bw / 2);
+               rcvr_mode = MT2063_OFFAIR_ANALOG;
+               break;
+       case V4L2_TUNER_ANALOG_TV:
+               rcvr_mode = MT2063_CABLE_ANALOG;
+               if (params->std & ~V4L2_STD_MN) {
+                       pict_car = 38900000;
+                       ch_bw = 6000000;
+                       pict2chanb_vsb = -1250000;
+               } else if (params->std & V4L2_STD_PAL_G) {
+                       pict_car = 38900000;
+                       ch_bw = 7000000;
+                       pict2chanb_vsb = -1250000;
+               } else {                /* PAL/SECAM standards */
+                       pict_car = 38900000;
+                       ch_bw = 8000000;
+                       pict2chanb_vsb = -1250000;
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+       if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
+
+       state->AS_Data.f_LO2_Step = 125000;     /* FIXME: probably 5000 for FM */
+       state->AS_Data.f_out = if_mid;
+       state->AS_Data.f_out_bw = ch_bw + 750000;
+       status = MT2063_SetReceiverMode(state, rcvr_mode);
+       if (status < 0)
+               return status;
+
+       dprintk(1, "Tuning to frequency: %d, bandwidth %d, foffset %d\n",
+               params->frequency, ch_bw, pict2chanb_vsb);
+
+       status = MT2063_Tune(state, (params->frequency + (pict2chanb_vsb + (ch_bw / 2))));
+       if (status < 0)
+               return status;
+
+       state->frequency = params->frequency;
+       return 0;
+}
+
+/*
+ * As defined on EN 300 429, the DVB-C roll-off factor is 0.15.
+ * So, the amount of the needed bandwith is given by:
+ *     Bw = Symbol_rate * (1 + 0.15)
+ * As such, the maximum symbol rate supported by 6 MHz is given by:
+ *     max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds
+ */
+#define MAX_SYMBOL_RATE_6MHz   5217391
+
+static int mt2063_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct mt2063_state *state = fe->tuner_priv;
+       int status;
+       s32 pict_car;
+       s32 pict2chanb_vsb;
+       s32 ch_bw;
+       s32 if_mid;
+       s32 rcvr_mode;
+
+       if (!state->init) {
+               status = mt2063_init(fe);
+               if (status < 0)
+                       return status;
+       }
+
+       dprintk(2, "\n");
+
+       if (c->bandwidth_hz == 0)
+               return -EINVAL;
+       if (c->bandwidth_hz <= 6000000)
+               ch_bw = 6000000;
+       else if (c->bandwidth_hz <= 7000000)
+               ch_bw = 7000000;
+       else
+               ch_bw = 8000000;
+
+       switch (c->delivery_system) {
+       case SYS_DVBT:
+               rcvr_mode = MT2063_OFFAIR_COFDM;
+               pict_car = 36125000;
+               pict2chanb_vsb = -(ch_bw / 2);
+               break;
+       case SYS_DVBC_ANNEX_A:
+       case SYS_DVBC_ANNEX_C:
+               rcvr_mode = MT2063_CABLE_QAM;
+               pict_car = 36125000;
+               pict2chanb_vsb = -(ch_bw / 2);
+               break;
+       default:
+               return -EINVAL;
+       }
+       if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
+
+       state->AS_Data.f_LO2_Step = 125000;     /* FIXME: probably 5000 for FM */
+       state->AS_Data.f_out = if_mid;
+       state->AS_Data.f_out_bw = ch_bw + 750000;
+       status = MT2063_SetReceiverMode(state, rcvr_mode);
+       if (status < 0)
+               return status;
+
+       dprintk(1, "Tuning to frequency: %d, bandwidth %d, foffset %d\n",
+               c->frequency, ch_bw, pict2chanb_vsb);
+
+       status = MT2063_Tune(state, (c->frequency + (pict2chanb_vsb + (ch_bw / 2))));
+
+       if (status < 0)
+               return status;
+
+       state->frequency = c->frequency;
+       return 0;
+}
+
+static int mt2063_get_if_frequency(struct dvb_frontend *fe, u32 *freq)
+{
+       struct mt2063_state *state = fe->tuner_priv;
+
+       dprintk(2, "\n");
+
+       if (!state->init)
+               return -ENODEV;
+
+       *freq = state->AS_Data.f_out;
+
+       dprintk(1, "IF frequency: %d\n", *freq);
+
+       return 0;
+}
+
+static int mt2063_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
+{
+       struct mt2063_state *state = fe->tuner_priv;
+
+       dprintk(2, "\n");
+
+       if (!state->init)
+               return -ENODEV;
+
+       *bw = state->AS_Data.f_out_bw - 750000;
+
+       dprintk(1, "bandwidth: %d\n", *bw);
+
+       return 0;
+}
+
+static struct dvb_tuner_ops mt2063_ops = {
+       .info = {
+                .name = "MT2063 Silicon Tuner",
+                .frequency_min = 45000000,
+                .frequency_max = 865000000,
+                .frequency_step = 0,
+                },
+
+       .init = mt2063_init,
+       .sleep = MT2063_Sleep,
+       .get_status = mt2063_get_status,
+       .set_analog_params = mt2063_set_analog_params,
+       .set_params    = mt2063_set_params,
+       .get_if_frequency = mt2063_get_if_frequency,
+       .get_bandwidth = mt2063_get_bandwidth,
+       .release = mt2063_release,
+};
+
+struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
+                                  struct mt2063_config *config,
+                                  struct i2c_adapter *i2c)
+{
+       struct mt2063_state *state = NULL;
+
+       dprintk(2, "\n");
+
+       state = kzalloc(sizeof(struct mt2063_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       state->config = config;
+       state->i2c = i2c;
+       state->frontend = fe;
+       state->reference = config->refclock / 1000;     /* kHz */
+       fe->tuner_priv = state;
+       fe->ops.tuner_ops = mt2063_ops;
+
+       printk(KERN_INFO "%s: Attaching MT2063\n", __func__);
+       return fe;
+
+error:
+       kfree(state);
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(mt2063_attach);
+
+/*
+ * Ancillary routines visible outside mt2063
+ * FIXME: Remove them in favor of using standard tuner callbacks
+ */
+unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe)
+{
+       struct mt2063_state *state = fe->tuner_priv;
+       int err = 0;
+
+       dprintk(2, "\n");
+
+       err = MT2063_SoftwareShutdown(state, 1);
+       if (err < 0)
+               printk(KERN_ERR "%s: Couldn't shutdown\n", __func__);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(tuner_MT2063_SoftwareShutdown);
+
+unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe)
+{
+       struct mt2063_state *state = fe->tuner_priv;
+       int err = 0;
+
+       dprintk(2, "\n");
+
+       err = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
+       if (err < 0)
+               printk(KERN_ERR "%s: Invalid parameter\n", __func__);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(tuner_MT2063_ClearPowerMaskBits);
+
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_DESCRIPTION("MT2063 Silicon tuner");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/mt2063.h b/drivers/media/tuners/mt2063.h
new file mode 100644 (file)
index 0000000..3f5cfd9
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef __MT2063_H__
+#define __MT2063_H__
+
+#include "dvb_frontend.h"
+
+struct mt2063_config {
+       u8 tuner_address;
+       u32 refclock;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_MT2063) || (defined(CONFIG_MEDIA_TUNER_MT2063_MODULE) && defined(MODULE))
+struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
+                                  struct mt2063_config *config,
+                                  struct i2c_adapter *i2c);
+
+#else
+
+static inline struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
+                                  struct mt2063_config *config,
+                                  struct i2c_adapter *i2c)
+{
+       printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+
+/* FIXME: Should use the standard DVB attachment interfaces */
+unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe);
+unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe);
+
+#endif /* CONFIG_DVB_MT2063 */
+
+#endif /* __MT2063_H__ */
diff --git a/drivers/media/tuners/mt20xx.c b/drivers/media/tuners/mt20xx.c
new file mode 100644 (file)
index 0000000..0e74e97
--- /dev/null
@@ -0,0 +1,670 @@
+/*
+ * i2c tv tuner chip device driver
+ * controls microtune tuners, mt2032 + mt2050 at the moment.
+ *
+ * This "mt20xx" module was split apart from the original "tuner" module.
+ */
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+#include "tuner-i2c.h"
+#include "mt20xx.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable verbose debug messages");
+
+/* ---------------------------------------------------------------------- */
+
+static unsigned int optimize_vco  = 1;
+module_param(optimize_vco,      int, 0644);
+
+static unsigned int tv_antenna    = 1;
+module_param(tv_antenna,        int, 0644);
+
+static unsigned int radio_antenna;
+module_param(radio_antenna,     int, 0644);
+
+/* ---------------------------------------------------------------------- */
+
+#define MT2032 0x04
+#define MT2030 0x06
+#define MT2040 0x07
+#define MT2050 0x42
+
+static char *microtune_part[] = {
+       [ MT2030 ] = "MT2030",
+       [ MT2032 ] = "MT2032",
+       [ MT2040 ] = "MT2040",
+       [ MT2050 ] = "MT2050",
+};
+
+struct microtune_priv {
+       struct tuner_i2c_props i2c_props;
+
+       unsigned int xogc;
+       //unsigned int radio_if2;
+
+       u32 frequency;
+};
+
+static int microtune_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+
+       return 0;
+}
+
+static int microtune_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct microtune_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+// IsSpurInBand()?
+static int mt2032_spurcheck(struct dvb_frontend *fe,
+                           int f1, int f2, int spectrum_from,int spectrum_to)
+{
+       struct microtune_priv *priv = fe->tuner_priv;
+       int n1=1,n2,f;
+
+       f1=f1/1000; //scale to kHz to avoid 32bit overflows
+       f2=f2/1000;
+       spectrum_from/=1000;
+       spectrum_to/=1000;
+
+       tuner_dbg("spurcheck f1=%d f2=%d  from=%d to=%d\n",
+                 f1,f2,spectrum_from,spectrum_to);
+
+       do {
+           n2=-n1;
+           f=n1*(f1-f2);
+           do {
+               n2--;
+               f=f-f2;
+               tuner_dbg("spurtest n1=%d n2=%d ftest=%d\n",n1,n2,f);
+
+               if( (f>spectrum_from) && (f<spectrum_to))
+                       tuner_dbg("mt2032 spurcheck triggered: %d\n",n1);
+           } while ( (f>(f2-spectrum_to)) || (n2>-5));
+           n1++;
+       } while (n1<5);
+
+       return 1;
+}
+
+static int mt2032_compute_freq(struct dvb_frontend *fe,
+                              unsigned int rfin,
+                              unsigned int if1, unsigned int if2,
+                              unsigned int spectrum_from,
+                              unsigned int spectrum_to,
+                              unsigned char *buf,
+                              int *ret_sel,
+                              unsigned int xogc) //all in Hz
+{
+       struct microtune_priv *priv = fe->tuner_priv;
+       unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1,
+               desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq;
+
+       fref= 5250 *1000; //5.25MHz
+       desired_lo1=rfin+if1;
+
+       lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000);
+       lo1n=lo1/8;
+       lo1a=lo1-(lo1n*8);
+
+       s=rfin/1000/1000+1090;
+
+       if(optimize_vco) {
+               if(s>1890) sel=0;
+               else if(s>1720) sel=1;
+               else if(s>1530) sel=2;
+               else if(s>1370) sel=3;
+               else sel=4; // >1090
+       }
+       else {
+               if(s>1790) sel=0; // <1958
+               else if(s>1617) sel=1;
+               else if(s>1449) sel=2;
+               else if(s>1291) sel=3;
+               else sel=4; // >1090
+       }
+       *ret_sel=sel;
+
+       lo1freq=(lo1a+8*lo1n)*fref;
+
+       tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n",
+                 rfin,lo1,lo1n,lo1a,sel,lo1freq);
+
+       desired_lo2=lo1freq-rfin-if2;
+       lo2=(desired_lo2)/fref;
+       lo2n=lo2/8;
+       lo2a=lo2-(lo2n*8);
+       lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith
+       lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000;
+
+       tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n",
+                 rfin,lo2,lo2n,lo2a,lo2num,lo2freq);
+
+       if (lo1a > 7 || lo1n < 17 || lo1n > 48 || lo2a > 7 || lo2n < 17 ||
+                       lo2n > 30) {
+               tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n",
+                          lo1a, lo1n, lo2a,lo2n);
+               return(-1);
+       }
+
+       mt2032_spurcheck(fe, lo1freq, desired_lo2,  spectrum_from, spectrum_to);
+       // should recalculate lo1 (one step up/down)
+
+       // set up MT2032 register map for transfer over i2c
+       buf[0]=lo1n-1;
+       buf[1]=lo1a | (sel<<4);
+       buf[2]=0x86; // LOGC
+       buf[3]=0x0f; //reserved
+       buf[4]=0x1f;
+       buf[5]=(lo2n-1) | (lo2a<<5);
+       if(rfin >400*1000*1000)
+               buf[6]=0xe4;
+       else
+               buf[6]=0xf4; // set PKEN per rev 1.2
+       buf[7]=8+xogc;
+       buf[8]=0xc3; //reserved
+       buf[9]=0x4e; //reserved
+       buf[10]=0xec; //reserved
+       buf[11]=(lo2num&0xff);
+       buf[12]=(lo2num>>8) |0x80; // Lo2RST
+
+       return 0;
+}
+
+static int mt2032_check_lo_lock(struct dvb_frontend *fe)
+{
+       struct microtune_priv *priv = fe->tuner_priv;
+       int try,lock=0;
+       unsigned char buf[2];
+
+       for(try=0;try<10;try++) {
+               buf[0]=0x0e;
+               tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
+               tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
+               tuner_dbg("mt2032 Reg.E=0x%02x\n",buf[0]);
+               lock=buf[0] &0x06;
+
+               if (lock==6)
+                       break;
+
+               tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]);
+               udelay(1000);
+       }
+       return lock;
+}
+
+static int mt2032_optimize_vco(struct dvb_frontend *fe,int sel,int lock)
+{
+       struct microtune_priv *priv = fe->tuner_priv;
+       unsigned char buf[2];
+       int tad1;
+
+       buf[0]=0x0f;
+       tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
+       tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
+       tuner_dbg("mt2032 Reg.F=0x%02x\n",buf[0]);
+       tad1=buf[0]&0x07;
+
+       if(tad1 ==0) return lock;
+       if(tad1 ==1) return lock;
+
+       if(tad1==2) {
+               if(sel==0)
+                       return lock;
+               else sel--;
+       }
+       else {
+               if(sel<4)
+                       sel++;
+               else
+                       return lock;
+       }
+
+       tuner_dbg("mt2032 optimize_vco: sel=%d\n",sel);
+
+       buf[0]=0x0f;
+       buf[1]=sel;
+       tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
+       lock=mt2032_check_lo_lock(fe);
+       return lock;
+}
+
+
+static void mt2032_set_if_freq(struct dvb_frontend *fe, unsigned int rfin,
+                              unsigned int if1, unsigned int if2,
+                              unsigned int from, unsigned int to)
+{
+       unsigned char buf[21];
+       int lint_try,ret,sel,lock=0;
+       struct microtune_priv *priv = fe->tuner_priv;
+
+       tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n",
+                 rfin,if1,if2,from,to);
+
+       buf[0]=0;
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
+       tuner_i2c_xfer_recv(&priv->i2c_props,buf,21);
+
+       buf[0]=0;
+       ret=mt2032_compute_freq(fe,rfin,if1,if2,from,to,&buf[1],&sel,priv->xogc);
+       if (ret<0)
+               return;
+
+       // send only the relevant registers per Rev. 1.2
+       buf[0]=0;
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,4);
+       buf[5]=5;
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+5,4);
+       buf[11]=11;
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+11,3);
+       if(ret!=3)
+               tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret);
+
+       // wait for PLLs to lock (per manual), retry LINT if not.
+       for(lint_try=0; lint_try<2; lint_try++) {
+               lock=mt2032_check_lo_lock(fe);
+
+               if(optimize_vco)
+                       lock=mt2032_optimize_vco(fe,sel,lock);
+               if(lock==6) break;
+
+               tuner_dbg("mt2032: re-init PLLs by LINT\n");
+               buf[0]=7;
+               buf[1]=0x80 +8+priv->xogc; // set LINT to re-init PLLs
+               tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
+               mdelay(10);
+               buf[1]=8+priv->xogc;
+               tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
+       }
+
+       if (lock!=6)
+               tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n");
+
+       buf[0]=2;
+       buf[1]=0x20; // LOGC for optimal phase noise
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
+       if (ret!=2)
+               tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
+}
+
+
+static int mt2032_set_tv_freq(struct dvb_frontend *fe,
+                             struct analog_parameters *params)
+{
+       int if2,from,to;
+
+       // signal bandwidth and picture carrier
+       if (params->std & V4L2_STD_525_60) {
+               // NTSC
+               from = 40750*1000;
+               to   = 46750*1000;
+               if2  = 45750*1000;
+       } else {
+               // PAL
+               from = 32900*1000;
+               to   = 39900*1000;
+               if2  = 38900*1000;
+       }
+
+       mt2032_set_if_freq(fe, params->frequency*62500,
+                          1090*1000*1000, if2, from, to);
+
+       return 0;
+}
+
+static int mt2032_set_radio_freq(struct dvb_frontend *fe,
+                                struct analog_parameters *params)
+{
+       struct microtune_priv *priv = fe->tuner_priv;
+       int if2;
+
+       if (params->std & V4L2_STD_525_60) {
+               tuner_dbg("pinnacle ntsc\n");
+               if2 = 41300 * 1000;
+       } else {
+               tuner_dbg("pinnacle pal\n");
+               if2 = 33300 * 1000;
+       }
+
+       // per Manual for FM tuning: first if center freq. 1085 MHz
+       mt2032_set_if_freq(fe, params->frequency * 125 / 2,
+                          1085*1000*1000,if2,if2,if2);
+
+       return 0;
+}
+
+static int mt2032_set_params(struct dvb_frontend *fe,
+                            struct analog_parameters *params)
+{
+       struct microtune_priv *priv = fe->tuner_priv;
+       int ret = -EINVAL;
+
+       switch (params->mode) {
+       case V4L2_TUNER_RADIO:
+               ret = mt2032_set_radio_freq(fe, params);
+               priv->frequency = params->frequency * 125 / 2;
+               break;
+       case V4L2_TUNER_ANALOG_TV:
+       case V4L2_TUNER_DIGITAL_TV:
+               ret = mt2032_set_tv_freq(fe, params);
+               priv->frequency = params->frequency * 62500;
+               break;
+       }
+
+       return ret;
+}
+
+static struct dvb_tuner_ops mt2032_tuner_ops = {
+       .set_analog_params = mt2032_set_params,
+       .release           = microtune_release,
+       .get_frequency     = microtune_get_frequency,
+};
+
+// Initialization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
+static int mt2032_init(struct dvb_frontend *fe)
+{
+       struct microtune_priv *priv = fe->tuner_priv;
+       unsigned char buf[21];
+       int ret,xogc,xok=0;
+
+       // Initialize Registers per spec.
+       buf[1]=2; // Index to register 2
+       buf[2]=0xff;
+       buf[3]=0x0f;
+       buf[4]=0x1f;
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+1,4);
+
+       buf[5]=6; // Index register 6
+       buf[6]=0xe4;
+       buf[7]=0x8f;
+       buf[8]=0xc3;
+       buf[9]=0x4e;
+       buf[10]=0xec;
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+5,6);
+
+       buf[12]=13;  // Index register 13
+       buf[13]=0x32;
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+12,2);
+
+       // Adjust XOGC (register 7), wait for XOK
+       xogc=7;
+       do {
+               tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
+               mdelay(10);
+               buf[0]=0x0e;
+               tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
+               tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
+               xok=buf[0]&0x01;
+               tuner_dbg("mt2032: xok = 0x%02x\n",xok);
+               if (xok == 1) break;
+
+               xogc--;
+               tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
+               if (xogc == 3) {
+                       xogc=4; // min. 4 per spec
+                       break;
+               }
+               buf[0]=0x07;
+               buf[1]=0x88 + xogc;
+               ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
+               if (ret!=2)
+                       tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
+       } while (xok != 1 );
+       priv->xogc=xogc;
+
+       memcpy(&fe->ops.tuner_ops, &mt2032_tuner_ops, sizeof(struct dvb_tuner_ops));
+
+       return(1);
+}
+
+static void mt2050_set_antenna(struct dvb_frontend *fe, unsigned char antenna)
+{
+       struct microtune_priv *priv = fe->tuner_priv;
+       unsigned char buf[2];
+
+       buf[0] = 6;
+       buf[1] = antenna ? 0x11 : 0x10;
+       tuner_i2c_xfer_send(&priv->i2c_props, buf, 2);
+       tuner_dbg("mt2050: enabled antenna connector %d\n", antenna);
+}
+
+static void mt2050_set_if_freq(struct dvb_frontend *fe,unsigned int freq, unsigned int if2)
+{
+       struct microtune_priv *priv = fe->tuner_priv;
+       unsigned int if1=1218*1000*1000;
+       unsigned int f_lo1,f_lo2,lo1,lo2,f_lo1_modulo,f_lo2_modulo,num1,num2,div1a,div1b,div2a,div2b;
+       int ret;
+       unsigned char buf[6];
+
+       tuner_dbg("mt2050_set_if_freq freq=%d if1=%d if2=%d\n",
+                 freq,if1,if2);
+
+       f_lo1=freq+if1;
+       f_lo1=(f_lo1/1000000)*1000000;
+
+       f_lo2=f_lo1-freq-if2;
+       f_lo2=(f_lo2/50000)*50000;
+
+       lo1=f_lo1/4000000;
+       lo2=f_lo2/4000000;
+
+       f_lo1_modulo= f_lo1-(lo1*4000000);
+       f_lo2_modulo= f_lo2-(lo2*4000000);
+
+       num1=4*f_lo1_modulo/4000000;
+       num2=4096*(f_lo2_modulo/1000)/4000;
+
+       // todo spurchecks
+
+       div1a=(lo1/12)-1;
+       div1b=lo1-(div1a+1)*12;
+
+       div2a=(lo2/8)-1;
+       div2b=lo2-(div2a+1)*8;
+
+       if (debug > 1) {
+               tuner_dbg("lo1 lo2 = %d %d\n", lo1, lo2);
+               tuner_dbg("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n",
+                         num1,num2,div1a,div1b,div2a,div2b);
+       }
+
+       buf[0]=1;
+       buf[1]= 4*div1b + num1;
+       if(freq<275*1000*1000) buf[1] = buf[1]|0x80;
+
+       buf[2]=div1a;
+       buf[3]=32*div2b + num2/256;
+       buf[4]=num2-(num2/256)*256;
+       buf[5]=div2a;
+       if(num2!=0) buf[5]=buf[5]|0x40;
+
+       if (debug > 1) {
+               int i;
+               tuner_dbg("bufs is: ");
+               for(i=0;i<6;i++)
+                       printk("%x ",buf[i]);
+               printk("\n");
+       }
+
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,6);
+       if (ret!=6)
+               tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret);
+}
+
+static int mt2050_set_tv_freq(struct dvb_frontend *fe,
+                             struct analog_parameters *params)
+{
+       unsigned int if2;
+
+       if (params->std & V4L2_STD_525_60) {
+               // NTSC
+               if2 = 45750*1000;
+       } else {
+               // PAL
+               if2 = 38900*1000;
+       }
+       if (V4L2_TUNER_DIGITAL_TV == params->mode) {
+               // DVB (pinnacle 300i)
+               if2 = 36150*1000;
+       }
+       mt2050_set_if_freq(fe, params->frequency*62500, if2);
+       mt2050_set_antenna(fe, tv_antenna);
+
+       return 0;
+}
+
+static int mt2050_set_radio_freq(struct dvb_frontend *fe,
+                                struct analog_parameters *params)
+{
+       struct microtune_priv *priv = fe->tuner_priv;
+       int if2;
+
+       if (params->std & V4L2_STD_525_60) {
+               tuner_dbg("pinnacle ntsc\n");
+               if2 = 41300 * 1000;
+       } else {
+               tuner_dbg("pinnacle pal\n");
+               if2 = 33300 * 1000;
+       }
+
+       mt2050_set_if_freq(fe, params->frequency * 125 / 2, if2);
+       mt2050_set_antenna(fe, radio_antenna);
+
+       return 0;
+}
+
+static int mt2050_set_params(struct dvb_frontend *fe,
+                            struct analog_parameters *params)
+{
+       struct microtune_priv *priv = fe->tuner_priv;
+       int ret = -EINVAL;
+
+       switch (params->mode) {
+       case V4L2_TUNER_RADIO:
+               ret = mt2050_set_radio_freq(fe, params);
+               priv->frequency = params->frequency * 125 / 2;
+               break;
+       case V4L2_TUNER_ANALOG_TV:
+       case V4L2_TUNER_DIGITAL_TV:
+               ret = mt2050_set_tv_freq(fe, params);
+               priv->frequency = params->frequency * 62500;
+               break;
+       }
+
+       return ret;
+}
+
+static struct dvb_tuner_ops mt2050_tuner_ops = {
+       .set_analog_params = mt2050_set_params,
+       .release           = microtune_release,
+       .get_frequency     = microtune_get_frequency,
+};
+
+static int mt2050_init(struct dvb_frontend *fe)
+{
+       struct microtune_priv *priv = fe->tuner_priv;
+       unsigned char buf[2];
+
+       buf[0] = 6;
+       buf[1] = 0x10;
+       tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); /* power */
+
+       buf[0] = 0x0f;
+       buf[1] = 0x0f;
+       tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); /* m1lo */
+
+       buf[0] = 0x0d;
+       tuner_i2c_xfer_send(&priv->i2c_props, buf, 1);
+       tuner_i2c_xfer_recv(&priv->i2c_props, buf, 1);
+
+       tuner_dbg("mt2050: sro is %x\n", buf[0]);
+
+       memcpy(&fe->ops.tuner_ops, &mt2050_tuner_ops, sizeof(struct dvb_tuner_ops));
+
+       return 0;
+}
+
+struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
+                                     struct i2c_adapter* i2c_adap,
+                                     u8 i2c_addr)
+{
+       struct microtune_priv *priv = NULL;
+       char *name;
+       unsigned char buf[21];
+       int company_code;
+
+       priv = kzalloc(sizeof(struct microtune_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+       fe->tuner_priv = priv;
+
+       priv->i2c_props.addr = i2c_addr;
+       priv->i2c_props.adap = i2c_adap;
+       priv->i2c_props.name = "mt20xx";
+
+       //priv->radio_if2 = 10700 * 1000;       /* 10.7MHz - FM radio */
+
+       memset(buf,0,sizeof(buf));
+
+       name = "unknown";
+
+       tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
+       tuner_i2c_xfer_recv(&priv->i2c_props,buf,21);
+       if (debug) {
+               int i;
+               tuner_dbg("MT20xx hexdump:");
+               for(i=0;i<21;i++) {
+                       printk(" %02x",buf[i]);
+                       if(((i+1)%8)==0) printk(" ");
+               }
+               printk("\n");
+       }
+       company_code = buf[0x11] << 8 | buf[0x12];
+       tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n",
+                  company_code,buf[0x13],buf[0x14]);
+
+
+       if (buf[0x13] < ARRAY_SIZE(microtune_part) &&
+           NULL != microtune_part[buf[0x13]])
+               name = microtune_part[buf[0x13]];
+       switch (buf[0x13]) {
+       case MT2032:
+               mt2032_init(fe);
+               break;
+       case MT2050:
+               mt2050_init(fe);
+               break;
+       default:
+               tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n",
+                          name);
+               return NULL;
+       }
+
+       strlcpy(fe->ops.tuner_ops.info.name, name,
+               sizeof(fe->ops.tuner_ops.info.name));
+       tuner_info("microtune %s found, OK\n",name);
+       return fe;
+}
+
+EXPORT_SYMBOL_GPL(microtune_attach);
+
+MODULE_DESCRIPTION("Microtune tuner driver");
+MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
+MODULE_LICENSE("GPL");
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/tuners/mt20xx.h b/drivers/media/tuners/mt20xx.h
new file mode 100644 (file)
index 0000000..259553a
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+    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 __MT20XX_H__
+#define __MT20XX_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+#if defined(CONFIG_MEDIA_TUNER_MT20XX) || (defined(CONFIG_MEDIA_TUNER_MT20XX_MODULE) && defined(MODULE))
+extern struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
+                                            struct i2c_adapter* i2c_adap,
+                                            u8 i2c_addr);
+#else
+static inline struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
+                                            struct i2c_adapter* i2c_adap,
+                                            u8 i2c_addr)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* __MT20XX_H__ */
diff --git a/drivers/media/tuners/mt2131.c b/drivers/media/tuners/mt2131.c
new file mode 100644 (file)
index 0000000..f83b0c1
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
+ *
+ *  Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
+ *
+ *  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.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+
+#include "mt2131.h"
+#include "mt2131_priv.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+#define dprintk(level,fmt, arg...) if (debug >= level) \
+       printk(KERN_INFO "%s: " fmt, "mt2131", ## arg)
+
+static u8 mt2131_config1[] = {
+       0x01,
+       0x50, 0x00, 0x50, 0x80, 0x00, 0x49, 0xfa, 0x88,
+       0x08, 0x77, 0x41, 0x04, 0x00, 0x00, 0x00, 0x32,
+       0x7f, 0xda, 0x4c, 0x00, 0x10, 0xaa, 0x78, 0x80,
+       0xff, 0x68, 0xa0, 0xff, 0xdd, 0x00, 0x00
+};
+
+static u8 mt2131_config2[] = {
+       0x10,
+       0x7f, 0xc8, 0x0a, 0x5f, 0x00, 0x04
+};
+
+static int mt2131_readreg(struct mt2131_priv *priv, u8 reg, u8 *val)
+{
+       struct i2c_msg msg[2] = {
+               { .addr = priv->cfg->i2c_address, .flags = 0,
+                 .buf = &reg, .len = 1 },
+               { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
+                 .buf = val,  .len = 1 },
+       };
+
+       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
+               printk(KERN_WARNING "mt2131 I2C read failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int mt2131_writereg(struct mt2131_priv *priv, u8 reg, u8 val)
+{
+       u8 buf[2] = { reg, val };
+       struct i2c_msg msg = { .addr = priv->cfg->i2c_address, .flags = 0,
+                              .buf = buf, .len = 2 };
+
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "mt2131 I2C write failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int mt2131_writeregs(struct mt2131_priv *priv,u8 *buf, u8 len)
+{
+       struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
+                              .flags = 0, .buf = buf, .len = len };
+
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "mt2131 I2C write failed (len=%i)\n",
+                      (int)len);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int mt2131_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct mt2131_priv *priv;
+       int ret=0, i;
+       u32 freq;
+       u8  if_band_center;
+       u32 f_lo1, f_lo2;
+       u32 div1, num1, div2, num2;
+       u8  b[8];
+       u8 lockval = 0;
+
+       priv = fe->tuner_priv;
+
+       freq = c->frequency / 1000;  /* Hz -> kHz */
+       dprintk(1, "%s() freq=%d\n", __func__, freq);
+
+       f_lo1 = freq + MT2131_IF1 * 1000;
+       f_lo1 = (f_lo1 / 250) * 250;
+       f_lo2 = f_lo1 - freq - MT2131_IF2;
+
+       priv->frequency =  (f_lo1 - f_lo2 - MT2131_IF2) * 1000;
+
+       /* Frequency LO1 = 16MHz * (DIV1 + NUM1/8192 ) */
+       num1 = f_lo1 * 64 / (MT2131_FREF / 128);
+       div1 = num1 / 8192;
+       num1 &= 0x1fff;
+
+       /* Frequency LO2 = 16MHz * (DIV2 + NUM2/8192 ) */
+       num2 = f_lo2 * 64 / (MT2131_FREF / 128);
+       div2 = num2 / 8192;
+       num2 &= 0x1fff;
+
+       if (freq <=   82500) if_band_center = 0x00; else
+       if (freq <=  137500) if_band_center = 0x01; else
+       if (freq <=  192500) if_band_center = 0x02; else
+       if (freq <=  247500) if_band_center = 0x03; else
+       if (freq <=  302500) if_band_center = 0x04; else
+       if (freq <=  357500) if_band_center = 0x05; else
+       if (freq <=  412500) if_band_center = 0x06; else
+       if (freq <=  467500) if_band_center = 0x07; else
+       if (freq <=  522500) if_band_center = 0x08; else
+       if (freq <=  577500) if_band_center = 0x09; else
+       if (freq <=  632500) if_band_center = 0x0A; else
+       if (freq <=  687500) if_band_center = 0x0B; else
+       if (freq <=  742500) if_band_center = 0x0C; else
+       if (freq <=  797500) if_band_center = 0x0D; else
+       if (freq <=  852500) if_band_center = 0x0E; else
+       if (freq <=  907500) if_band_center = 0x0F; else
+       if (freq <=  962500) if_band_center = 0x10; else
+       if (freq <= 1017500) if_band_center = 0x11; else
+       if (freq <= 1072500) if_band_center = 0x12; else if_band_center = 0x13;
+
+       b[0] = 1;
+       b[1] = (num1 >> 5) & 0xFF;
+       b[2] = (num1 & 0x1F);
+       b[3] = div1;
+       b[4] = (num2 >> 5) & 0xFF;
+       b[5] = num2 & 0x1F;
+       b[6] = div2;
+
+       dprintk(1, "IF1: %dMHz IF2: %dMHz\n", MT2131_IF1, MT2131_IF2);
+       dprintk(1, "PLL freq=%dkHz  band=%d\n", (int)freq, (int)if_band_center);
+       dprintk(1, "PLL f_lo1=%dkHz  f_lo2=%dkHz\n", (int)f_lo1, (int)f_lo2);
+       dprintk(1, "PLL div1=%d  num1=%d  div2=%d  num2=%d\n",
+               (int)div1, (int)num1, (int)div2, (int)num2);
+       dprintk(1, "PLL [1..6]: %2x %2x %2x %2x %2x %2x\n",
+               (int)b[1], (int)b[2], (int)b[3], (int)b[4], (int)b[5],
+               (int)b[6]);
+
+       ret = mt2131_writeregs(priv,b,7);
+       if (ret < 0)
+               return ret;
+
+       mt2131_writereg(priv, 0x0b, if_band_center);
+
+       /* Wait for lock */
+       i = 0;
+       do {
+               mt2131_readreg(priv, 0x08, &lockval);
+               if ((lockval & 0x88) == 0x88)
+                       break;
+               msleep(4);
+               i++;
+       } while (i < 10);
+
+       return ret;
+}
+
+static int mt2131_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct mt2131_priv *priv = fe->tuner_priv;
+       dprintk(1, "%s()\n", __func__);
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static int mt2131_get_status(struct dvb_frontend *fe, u32 *status)
+{
+       struct mt2131_priv *priv = fe->tuner_priv;
+       u8 lock_status = 0;
+       u8 afc_status = 0;
+
+       *status = 0;
+
+       mt2131_readreg(priv, 0x08, &lock_status);
+       if ((lock_status & 0x88) == 0x88)
+               *status = TUNER_STATUS_LOCKED;
+
+       mt2131_readreg(priv, 0x09, &afc_status);
+       dprintk(1, "%s() - LO Status = 0x%x, AFC Status = 0x%x\n",
+               __func__, lock_status, afc_status);
+
+       return 0;
+}
+
+static int mt2131_init(struct dvb_frontend *fe)
+{
+       struct mt2131_priv *priv = fe->tuner_priv;
+       int ret;
+       dprintk(1, "%s()\n", __func__);
+
+       if ((ret = mt2131_writeregs(priv, mt2131_config1,
+                                   sizeof(mt2131_config1))) < 0)
+               return ret;
+
+       mt2131_writereg(priv, 0x0b, 0x09);
+       mt2131_writereg(priv, 0x15, 0x47);
+       mt2131_writereg(priv, 0x07, 0xf2);
+       mt2131_writereg(priv, 0x0b, 0x01);
+
+       if ((ret = mt2131_writeregs(priv, mt2131_config2,
+                                   sizeof(mt2131_config2))) < 0)
+               return ret;
+
+       return ret;
+}
+
+static int mt2131_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 mt2131_tuner_ops = {
+       .info = {
+               .name           = "Microtune MT2131",
+               .frequency_min  =  48000000,
+               .frequency_max  = 860000000,
+               .frequency_step =     50000,
+       },
+
+       .release       = mt2131_release,
+       .init          = mt2131_init,
+
+       .set_params    = mt2131_set_params,
+       .get_frequency = mt2131_get_frequency,
+       .get_status    = mt2131_get_status
+};
+
+struct dvb_frontend * mt2131_attach(struct dvb_frontend *fe,
+                                   struct i2c_adapter *i2c,
+                                   struct mt2131_config *cfg, u16 if1)
+{
+       struct mt2131_priv *priv = NULL;
+       u8 id = 0;
+
+       dprintk(1, "%s()\n", __func__);
+
+       priv = kzalloc(sizeof(struct mt2131_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->cfg = cfg;
+       priv->i2c = i2c;
+
+       if (mt2131_readreg(priv, 0, &id) != 0) {
+               kfree(priv);
+               return NULL;
+       }
+       if ( (id != 0x3E) && (id != 0x3F) ) {
+               printk(KERN_ERR "MT2131: Device not found at addr 0x%02x\n",
+                      cfg->i2c_address);
+               kfree(priv);
+               return NULL;
+       }
+
+       printk(KERN_INFO "MT2131: successfully identified at address 0x%02x\n",
+              cfg->i2c_address);
+       memcpy(&fe->ops.tuner_ops, &mt2131_tuner_ops,
+              sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = priv;
+       return fe;
+}
+EXPORT_SYMBOL(mt2131_attach);
+
+MODULE_AUTHOR("Steven Toth");
+MODULE_DESCRIPTION("Microtune MT2131 silicon tuner driver");
+MODULE_LICENSE("GPL");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
diff --git a/drivers/media/tuners/mt2131.h b/drivers/media/tuners/mt2131.h
new file mode 100644 (file)
index 0000000..6632de6
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
+ *
+ *  Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
+ *
+ *  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 __MT2131_H__
+#define __MT2131_H__
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct mt2131_config {
+       u8 i2c_address;
+       u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
+};
+
+#if defined(CONFIG_MEDIA_TUNER_MT2131) || (defined(CONFIG_MEDIA_TUNER_MT2131_MODULE) && defined(MODULE))
+extern struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
+                                         struct i2c_adapter *i2c,
+                                         struct mt2131_config *cfg,
+                                         u16 if1);
+#else
+static inline struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
+                                                struct i2c_adapter *i2c,
+                                                struct mt2131_config *cfg,
+                                                u16 if1)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_MEDIA_TUNER_MT2131 */
+
+#endif /* __MT2131_H__ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
diff --git a/drivers/media/tuners/mt2131_priv.h b/drivers/media/tuners/mt2131_priv.h
new file mode 100644 (file)
index 0000000..62aeedf
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
+ *
+ *  Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
+ *
+ *  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 __MT2131_PRIV_H__
+#define __MT2131_PRIV_H__
+
+/* Regs */
+#define MT2131_PWR              0x07
+#define MT2131_UPC_1            0x0b
+#define MT2131_AGC_RL           0x10
+#define MT2131_MISC_2           0x15
+
+/* frequency values in KHz */
+#define MT2131_IF1              1220
+#define MT2131_IF2              44000
+#define MT2131_FREF             16000
+
+struct mt2131_priv {
+       struct mt2131_config *cfg;
+       struct i2c_adapter   *i2c;
+
+       u32 frequency;
+};
+
+#endif /* __MT2131_PRIV_H__ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
diff --git a/drivers/media/tuners/mt2266.c b/drivers/media/tuners/mt2266.c
new file mode 100644 (file)
index 0000000..bca4d75
--- /dev/null
@@ -0,0 +1,353 @@
+/*
+ *  Driver for Microtune MT2266 "Direct conversion low power broadband tuner"
+ *
+ *  Copyright (c) 2007 Olivier DANET <odanet@caramail.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.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+
+#include "dvb_frontend.h"
+#include "mt2266.h"
+
+#define I2C_ADDRESS 0x60
+
+#define REG_PART_REV   0
+#define REG_TUNE       1
+#define REG_BAND       6
+#define REG_BANDWIDTH  8
+#define REG_LOCK       0x12
+
+#define PART_REV 0x85
+
+struct mt2266_priv {
+       struct mt2266_config *cfg;
+       struct i2c_adapter   *i2c;
+
+       u32 frequency;
+       u32 bandwidth;
+       u8 band;
+};
+
+#define MT2266_VHF 1
+#define MT2266_UHF 0
+
+/* Here, frequencies are expressed in kiloHertz to avoid 32 bits overflows */
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+#define dprintk(args...) do { if (debug) {printk(KERN_DEBUG "MT2266: " args); printk("\n"); }} while (0)
+
+// Reads a single register
+static int mt2266_readreg(struct mt2266_priv *priv, u8 reg, u8 *val)
+{
+       struct i2c_msg msg[2] = {
+               { .addr = priv->cfg->i2c_address, .flags = 0,        .buf = &reg, .len = 1 },
+               { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val,  .len = 1 },
+       };
+       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
+               printk(KERN_WARNING "MT2266 I2C read failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+// Writes a single register
+static int mt2266_writereg(struct mt2266_priv *priv, u8 reg, u8 val)
+{
+       u8 buf[2] = { reg, val };
+       struct i2c_msg msg = {
+               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2
+       };
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "MT2266 I2C write failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+// Writes a set of consecutive registers
+static int mt2266_writeregs(struct mt2266_priv *priv,u8 *buf, u8 len)
+{
+       struct i2c_msg msg = {
+               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = len
+       };
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "MT2266 I2C write failed (len=%i)\n",(int)len);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+// Initialisation sequences
+static u8 mt2266_init1[] = { REG_TUNE, 0x00, 0x00, 0x28,
+                                0x00, 0x52, 0x99, 0x3f };
+
+static u8 mt2266_init2[] = {
+    0x17, 0x6d, 0x71, 0x61, 0xc0, 0xbf, 0xff, 0xdc, 0x00, 0x0a, 0xd4,
+    0x03, 0x64, 0x64, 0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7f, 0x5e, 0x3f, 0xff, 0xff,
+    0xff, 0x00, 0x77, 0x0f, 0x2d
+};
+
+static u8 mt2266_init_8mhz[] = { REG_BANDWIDTH, 0x22, 0x22, 0x22, 0x22,
+                                               0x22, 0x22, 0x22, 0x22 };
+
+static u8 mt2266_init_7mhz[] = { REG_BANDWIDTH, 0x32, 0x32, 0x32, 0x32,
+                                               0x32, 0x32, 0x32, 0x32 };
+
+static u8 mt2266_init_6mhz[] = { REG_BANDWIDTH, 0xa7, 0xa7, 0xa7, 0xa7,
+                                               0xa7, 0xa7, 0xa7, 0xa7 };
+
+static u8 mt2266_uhf[] = { 0x1d, 0xdc, 0x00, 0x0a, 0xd4, 0x03, 0x64, 0x64,
+                          0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14 };
+
+static u8 mt2266_vhf[] = { 0x1d, 0xfe, 0x00, 0x00, 0xb4, 0x03, 0xa5, 0xa5,
+                          0xa5, 0xa5, 0x82, 0xaa, 0xf1, 0x17, 0x80, 0x1f };
+
+#define FREF 30000       // Quartz oscillator 30 MHz
+
+static int mt2266_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct mt2266_priv *priv;
+       int ret=0;
+       u32 freq;
+       u32 tune;
+       u8  lnaband;
+       u8  b[10];
+       int i;
+       u8 band;
+
+       priv = fe->tuner_priv;
+
+       freq = priv->frequency / 1000; /* Hz -> kHz */
+       if (freq < 470000 && freq > 230000)
+               return -EINVAL; /* Gap between VHF and UHF bands */
+
+       priv->frequency = c->frequency;
+       tune = 2 * freq * (8192/16) / (FREF/16);
+       band = (freq < 300000) ? MT2266_VHF : MT2266_UHF;
+       if (band == MT2266_VHF)
+               tune *= 2;
+
+       switch (c->bandwidth_hz) {
+       case 6000000:
+               mt2266_writeregs(priv, mt2266_init_6mhz,
+                                sizeof(mt2266_init_6mhz));
+               break;
+       case 8000000:
+               mt2266_writeregs(priv, mt2266_init_8mhz,
+                                sizeof(mt2266_init_8mhz));
+               break;
+       case 7000000:
+       default:
+               mt2266_writeregs(priv, mt2266_init_7mhz,
+                                sizeof(mt2266_init_7mhz));
+               break;
+       }
+       priv->bandwidth = c->bandwidth_hz;
+
+       if (band == MT2266_VHF && priv->band == MT2266_UHF) {
+               dprintk("Switch from UHF to VHF");
+               mt2266_writereg(priv, 0x05, 0x04);
+               mt2266_writereg(priv, 0x19, 0x61);
+               mt2266_writeregs(priv, mt2266_vhf, sizeof(mt2266_vhf));
+       } else if (band == MT2266_UHF && priv->band == MT2266_VHF) {
+               dprintk("Switch from VHF to UHF");
+               mt2266_writereg(priv, 0x05, 0x52);
+               mt2266_writereg(priv, 0x19, 0x61);
+               mt2266_writeregs(priv, mt2266_uhf, sizeof(mt2266_uhf));
+       }
+       msleep(10);
+
+       if (freq <= 495000)
+               lnaband = 0xEE;
+       else if (freq <= 525000)
+               lnaband = 0xDD;
+       else if (freq <= 550000)
+               lnaband = 0xCC;
+       else if (freq <= 580000)
+               lnaband = 0xBB;
+       else if (freq <= 605000)
+               lnaband = 0xAA;
+       else if (freq <= 630000)
+               lnaband = 0x99;
+       else if (freq <= 655000)
+               lnaband = 0x88;
+       else if (freq <= 685000)
+               lnaband = 0x77;
+       else if (freq <= 710000)
+               lnaband = 0x66;
+       else if (freq <= 735000)
+               lnaband = 0x55;
+       else if (freq <= 765000)
+               lnaband = 0x44;
+       else if (freq <= 802000)
+               lnaband = 0x33;
+       else if (freq <= 840000)
+               lnaband = 0x22;
+       else
+               lnaband = 0x11;
+
+       b[0] = REG_TUNE;
+       b[1] = (tune >> 8) & 0x1F;
+       b[2] = tune & 0xFF;
+       b[3] = tune >> 13;
+       mt2266_writeregs(priv,b,4);
+
+       dprintk("set_parms: tune=%d band=%d %s",
+               (int) tune, (int) lnaband,
+               (band == MT2266_UHF) ? "UHF" : "VHF");
+       dprintk("set_parms: [1..3]: %2x %2x %2x",
+               (int) b[1], (int) b[2], (int)b[3]);
+
+       if (band == MT2266_UHF) {
+               b[0] = 0x05;
+               b[1] = (priv->band == MT2266_VHF) ? 0x52 : 0x62;
+               b[2] = lnaband;
+               mt2266_writeregs(priv, b, 3);
+       }
+
+       /* Wait for pll lock or timeout */
+       i = 0;
+       do {
+               mt2266_readreg(priv,REG_LOCK,b);
+               if (b[0] & 0x40)
+                       break;
+               msleep(10);
+               i++;
+       } while (i<10);
+       dprintk("Lock when i=%i",(int)i);
+
+       if (band == MT2266_UHF && priv->band == MT2266_VHF)
+               mt2266_writereg(priv, 0x05, 0x62);
+
+       priv->band = band;
+
+       return ret;
+}
+
+static void mt2266_calibrate(struct mt2266_priv *priv)
+{
+       mt2266_writereg(priv, 0x11, 0x03);
+       mt2266_writereg(priv, 0x11, 0x01);
+       mt2266_writeregs(priv, mt2266_init1, sizeof(mt2266_init1));
+       mt2266_writeregs(priv, mt2266_init2, sizeof(mt2266_init2));
+       mt2266_writereg(priv, 0x33, 0x5e);
+       mt2266_writereg(priv, 0x10, 0x10);
+       mt2266_writereg(priv, 0x10, 0x00);
+       mt2266_writeregs(priv, mt2266_init_8mhz, sizeof(mt2266_init_8mhz));
+       msleep(25);
+       mt2266_writereg(priv, 0x17, 0x6d);
+       mt2266_writereg(priv, 0x1c, 0x00);
+       msleep(75);
+       mt2266_writereg(priv, 0x17, 0x6d);
+       mt2266_writereg(priv, 0x1c, 0xff);
+}
+
+static int mt2266_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct mt2266_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static int mt2266_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct mt2266_priv *priv = fe->tuner_priv;
+       *bandwidth = priv->bandwidth;
+       return 0;
+}
+
+static int mt2266_init(struct dvb_frontend *fe)
+{
+       int ret;
+       struct mt2266_priv *priv = fe->tuner_priv;
+       ret = mt2266_writereg(priv, 0x17, 0x6d);
+       if (ret < 0)
+               return ret;
+       ret = mt2266_writereg(priv, 0x1c, 0xff);
+       if (ret < 0)
+               return ret;
+       return 0;
+}
+
+static int mt2266_sleep(struct dvb_frontend *fe)
+{
+       struct mt2266_priv *priv = fe->tuner_priv;
+       mt2266_writereg(priv, 0x17, 0x6d);
+       mt2266_writereg(priv, 0x1c, 0x00);
+       return 0;
+}
+
+static int mt2266_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static const struct dvb_tuner_ops mt2266_tuner_ops = {
+       .info = {
+               .name           = "Microtune MT2266",
+               .frequency_min  = 174000000,
+               .frequency_max  = 862000000,
+               .frequency_step =     50000,
+       },
+       .release       = mt2266_release,
+       .init          = mt2266_init,
+       .sleep         = mt2266_sleep,
+       .set_params    = mt2266_set_params,
+       .get_frequency = mt2266_get_frequency,
+       .get_bandwidth = mt2266_get_bandwidth
+};
+
+struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg)
+{
+       struct mt2266_priv *priv = NULL;
+       u8 id = 0;
+
+       priv = kzalloc(sizeof(struct mt2266_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->cfg      = cfg;
+       priv->i2c      = i2c;
+       priv->band     = MT2266_UHF;
+
+       if (mt2266_readreg(priv, 0, &id)) {
+               kfree(priv);
+               return NULL;
+       }
+       if (id != PART_REV) {
+               kfree(priv);
+               return NULL;
+       }
+       printk(KERN_INFO "MT2266: successfully identified\n");
+       memcpy(&fe->ops.tuner_ops, &mt2266_tuner_ops, sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = priv;
+       mt2266_calibrate(priv);
+       return fe;
+}
+EXPORT_SYMBOL(mt2266_attach);
+
+MODULE_AUTHOR("Olivier DANET");
+MODULE_DESCRIPTION("Microtune MT2266 silicon tuner driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/mt2266.h b/drivers/media/tuners/mt2266.h
new file mode 100644 (file)
index 0000000..4d08388
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  Driver for Microtune MT2266 "Direct conversion low power broadband tuner"
+ *
+ *  Copyright (c) 2007 Olivier DANET <odanet@caramail.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.
+ */
+
+#ifndef MT2266_H
+#define MT2266_H
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct mt2266_config {
+       u8 i2c_address;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_MT2266) || (defined(CONFIG_MEDIA_TUNER_MT2266_MODULE) && defined(MODULE))
+extern struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg);
+#else
+static inline struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_MEDIA_TUNER_MT2266
+
+#endif
diff --git a/drivers/media/tuners/mxl5005s.c b/drivers/media/tuners/mxl5005s.c
new file mode 100644 (file)
index 0000000..6133315
--- /dev/null
@@ -0,0 +1,4109 @@
+/*
+    MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
+
+    Copyright (C) 2008 MaxLinear
+    Copyright (C) 2006 Steven Toth <stoth@linuxtv.org>
+      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
+};
+
+/* MXL5005 Tuner Register Struct */
+struct TunerReg {
+       u16 Reg_Num;    /* Tuner Register Address */
+       u16 Reg_Val;    /* Current sw programmed value waiting to be written */
+};
+
+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
+};
+
+/*
+ * 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 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 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 Fref_TG;
+       u32 Fvco;
+
+       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.
+        *
+        * static u32 MXL_GetXtalInt(u32 Xtal_Freq)
+        * {
+        *      if ((Xtal_Freq % 1000000) == 0)
+        *              return (Xtal_Freq / 10000);
+        *      else
+        *              return (((Xtal_Freq / 1000000) + 1)*100);
+        * }
+        *
+        * u32 Xtal_Int = MXL_GetXtalInt(state->Fxtal);
+        * 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->config->qam_gain != 0)
+                       status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN,
+                                                  state->config->qam_gain);
+               else 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 = ARRAY_SIZE(RegAddr);
+
+       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 = ARRAY_SIZE(RegAddr);
+
+       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 = ARRAY_SIZE(RegAddr);
+
+       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@linuxtv.org>
+ */
+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)
+{
+       struct mxl5005s_state *state = fe->tuner_priv;
+
+       dprintk(1, "%s()\n", __func__);
+       state->current_mode = MXL_QAM;
+       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 mxl5005s_state *state = fe->tuner_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u32 delsys = c->delivery_system;
+       u32 bw = c->bandwidth_hz;
+       u32 req_mode, req_bw = 0;
+       int ret;
+
+       dprintk(1, "%s()\n", __func__);
+
+       switch (delsys) {
+       case SYS_ATSC:
+               req_mode = MXL_ATSC;
+               req_bw  = MXL5005S_BANDWIDTH_6MHZ;
+               break;
+       case SYS_DVBC_ANNEX_B:
+               req_mode = MXL_QAM;
+               req_bw  = MXL5005S_BANDWIDTH_6MHZ;
+               break;
+       default:        /* Assume DVB-T */
+               req_mode = MXL_DVBT;
+               switch (bw) {
+               case 6000000:
+                       req_bw = MXL5005S_BANDWIDTH_6MHZ;
+                       break;
+               case 7000000:
+                       req_bw = MXL5005S_BANDWIDTH_7MHZ;
+                       break;
+               case 8000000:
+               case 0:
+                       req_bw = MXL5005S_BANDWIDTH_8MHZ;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       /* Change tuner for new modulation type if reqd */
+       if (req_mode != state->current_mode ||
+           req_bw != state->Chan_Bandwidth) {
+               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__, c->frequency);
+               ret = mxl5005s_SetRfFreqHz(fe, c->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;
+
+       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");
diff --git a/drivers/media/tuners/mxl5005s.h b/drivers/media/tuners/mxl5005s.h
new file mode 100644 (file)
index 0000000..fc8a1ff
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+    MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
+
+    Copyright (C) 2008 MaxLinear
+    Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
+
+    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;
+
+       /* Some boards need to override the built-in logic for determining
+          the gain when in QAM mode (the HVR-1600 is one such case) */
+       u8 qam_gain;
+
+       /* 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 */
+
diff --git a/drivers/media/tuners/mxl5007t.c b/drivers/media/tuners/mxl5007t.c
new file mode 100644 (file)
index 0000000..69e453e
--- /dev/null
@@ -0,0 +1,928 @@
+/*
+ *  mxl5007t.c - driver for the MaxLinear MxL5007T silicon tuner
+ *
+ *  Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ *  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.
+ */
+
+#include <linux/i2c.h>
+#include <linux/types.h>
+#include <linux/videodev2.h>
+#include "tuner-i2c.h"
+#include "mxl5007t.h"
+
+static DEFINE_MUTEX(mxl5007t_list_mutex);
+static LIST_HEAD(hybrid_tuner_instance_list);
+
+static int mxl5007t_debug;
+module_param_named(debug, mxl5007t_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level");
+
+/* ------------------------------------------------------------------------- */
+
+#define mxl_printk(kern, fmt, arg...) \
+       printk(kern "%s: " fmt "\n", __func__, ##arg)
+
+#define mxl_err(fmt, arg...) \
+       mxl_printk(KERN_ERR, "%d: " fmt, __LINE__, ##arg)
+
+#define mxl_warn(fmt, arg...) \
+       mxl_printk(KERN_WARNING, fmt, ##arg)
+
+#define mxl_info(fmt, arg...) \
+       mxl_printk(KERN_INFO, fmt, ##arg)
+
+#define mxl_debug(fmt, arg...)                         \
+({                                                     \
+       if (mxl5007t_debug)                             \
+               mxl_printk(KERN_DEBUG, fmt, ##arg);     \
+})
+
+#define mxl_fail(ret)                                                  \
+({                                                                     \
+       int __ret;                                                      \
+       __ret = (ret < 0);                                              \
+       if (__ret)                                                      \
+               mxl_printk(KERN_ERR, "error %d on line %d",             \
+                          ret, __LINE__);                              \
+       __ret;                                                          \
+})
+
+/* ------------------------------------------------------------------------- */
+
+#define MHz 1000000
+
+enum mxl5007t_mode {
+       MxL_MODE_ISDBT     =    0,
+       MxL_MODE_DVBT      =    1,
+       MxL_MODE_ATSC      =    2,
+       MxL_MODE_CABLE     = 0x10,
+};
+
+enum mxl5007t_chip_version {
+       MxL_UNKNOWN_ID     = 0x00,
+       MxL_5007_V1_F1     = 0x11,
+       MxL_5007_V1_F2     = 0x12,
+       MxL_5007_V4        = 0x14,
+       MxL_5007_V2_100_F1 = 0x21,
+       MxL_5007_V2_100_F2 = 0x22,
+       MxL_5007_V2_200_F1 = 0x23,
+       MxL_5007_V2_200_F2 = 0x24,
+};
+
+struct reg_pair_t {
+       u8 reg;
+       u8 val;
+};
+
+/* ------------------------------------------------------------------------- */
+
+static struct reg_pair_t init_tab[] = {
+       { 0x02, 0x06 },
+       { 0x03, 0x48 },
+       { 0x05, 0x04 },
+       { 0x06, 0x10 },
+       { 0x2e, 0x15 }, /* OVERRIDE */
+       { 0x30, 0x10 }, /* OVERRIDE */
+       { 0x45, 0x58 }, /* OVERRIDE */
+       { 0x48, 0x19 }, /* OVERRIDE */
+       { 0x52, 0x03 }, /* OVERRIDE */
+       { 0x53, 0x44 }, /* OVERRIDE */
+       { 0x6a, 0x4b }, /* OVERRIDE */
+       { 0x76, 0x00 }, /* OVERRIDE */
+       { 0x78, 0x18 }, /* OVERRIDE */
+       { 0x7a, 0x17 }, /* OVERRIDE */
+       { 0x85, 0x06 }, /* OVERRIDE */
+       { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */
+       { 0, 0 }
+};
+
+static struct reg_pair_t init_tab_cable[] = {
+       { 0x02, 0x06 },
+       { 0x03, 0x48 },
+       { 0x05, 0x04 },
+       { 0x06, 0x10 },
+       { 0x09, 0x3f },
+       { 0x0a, 0x3f },
+       { 0x0b, 0x3f },
+       { 0x2e, 0x15 }, /* OVERRIDE */
+       { 0x30, 0x10 }, /* OVERRIDE */
+       { 0x45, 0x58 }, /* OVERRIDE */
+       { 0x48, 0x19 }, /* OVERRIDE */
+       { 0x52, 0x03 }, /* OVERRIDE */
+       { 0x53, 0x44 }, /* OVERRIDE */
+       { 0x6a, 0x4b }, /* OVERRIDE */
+       { 0x76, 0x00 }, /* OVERRIDE */
+       { 0x78, 0x18 }, /* OVERRIDE */
+       { 0x7a, 0x17 }, /* OVERRIDE */
+       { 0x85, 0x06 }, /* OVERRIDE */
+       { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */
+       { 0, 0 }
+};
+
+/* ------------------------------------------------------------------------- */
+
+static struct reg_pair_t reg_pair_rftune[] = {
+       { 0x0f, 0x00 }, /* abort tune */
+       { 0x0c, 0x15 },
+       { 0x0d, 0x40 },
+       { 0x0e, 0x0e },
+       { 0x1f, 0x87 }, /* OVERRIDE */
+       { 0x20, 0x1f }, /* OVERRIDE */
+       { 0x21, 0x87 }, /* OVERRIDE */
+       { 0x22, 0x1f }, /* OVERRIDE */
+       { 0x80, 0x01 }, /* freq dependent */
+       { 0x0f, 0x01 }, /* start tune */
+       { 0, 0 }
+};
+
+/* ------------------------------------------------------------------------- */
+
+struct mxl5007t_state {
+       struct list_head hybrid_tuner_instance_list;
+       struct tuner_i2c_props i2c_props;
+
+       struct mutex lock;
+
+       struct mxl5007t_config *config;
+
+       enum mxl5007t_chip_version chip_id;
+
+       struct reg_pair_t tab_init[ARRAY_SIZE(init_tab)];
+       struct reg_pair_t tab_init_cable[ARRAY_SIZE(init_tab_cable)];
+       struct reg_pair_t tab_rftune[ARRAY_SIZE(reg_pair_rftune)];
+
+       enum mxl5007t_if_freq if_freq;
+
+       u32 frequency;
+       u32 bandwidth;
+};
+
+/* ------------------------------------------------------------------------- */
+
+/* called by _init and _rftun to manipulate the register arrays */
+
+static void set_reg_bits(struct reg_pair_t *reg_pair, u8 reg, u8 mask, u8 val)
+{
+       unsigned int i = 0;
+
+       while (reg_pair[i].reg || reg_pair[i].val) {
+               if (reg_pair[i].reg == reg) {
+                       reg_pair[i].val &= ~mask;
+                       reg_pair[i].val |= val;
+               }
+               i++;
+
+       }
+       return;
+}
+
+static void copy_reg_bits(struct reg_pair_t *reg_pair1,
+                         struct reg_pair_t *reg_pair2)
+{
+       unsigned int i, j;
+
+       i = j = 0;
+
+       while (reg_pair1[i].reg || reg_pair1[i].val) {
+               while (reg_pair2[j].reg || reg_pair2[j].val) {
+                       if (reg_pair1[i].reg != reg_pair2[j].reg) {
+                               j++;
+                               continue;
+                       }
+                       reg_pair2[j].val = reg_pair1[i].val;
+                       break;
+               }
+               i++;
+       }
+       return;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void mxl5007t_set_mode_bits(struct mxl5007t_state *state,
+                                  enum mxl5007t_mode mode,
+                                  s32 if_diff_out_level)
+{
+       switch (mode) {
+       case MxL_MODE_ATSC:
+               set_reg_bits(state->tab_init, 0x06, 0x1f, 0x12);
+               break;
+       case MxL_MODE_DVBT:
+               set_reg_bits(state->tab_init, 0x06, 0x1f, 0x11);
+               break;
+       case MxL_MODE_ISDBT:
+               set_reg_bits(state->tab_init, 0x06, 0x1f, 0x10);
+               break;
+       case MxL_MODE_CABLE:
+               set_reg_bits(state->tab_init_cable, 0x09, 0xff, 0xc1);
+               set_reg_bits(state->tab_init_cable, 0x0a, 0xff,
+                            8 - if_diff_out_level);
+               set_reg_bits(state->tab_init_cable, 0x0b, 0xff, 0x17);
+               break;
+       default:
+               mxl_fail(-EINVAL);
+       }
+       return;
+}
+
+static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state,
+                                     enum mxl5007t_if_freq if_freq,
+                                     int invert_if)
+{
+       u8 val;
+
+       switch (if_freq) {
+       case MxL_IF_4_MHZ:
+               val = 0x00;
+               break;
+       case MxL_IF_4_5_MHZ:
+               val = 0x02;
+               break;
+       case MxL_IF_4_57_MHZ:
+               val = 0x03;
+               break;
+       case MxL_IF_5_MHZ:
+               val = 0x04;
+               break;
+       case MxL_IF_5_38_MHZ:
+               val = 0x05;
+               break;
+       case MxL_IF_6_MHZ:
+               val = 0x06;
+               break;
+       case MxL_IF_6_28_MHZ:
+               val = 0x07;
+               break;
+       case MxL_IF_9_1915_MHZ:
+               val = 0x08;
+               break;
+       case MxL_IF_35_25_MHZ:
+               val = 0x09;
+               break;
+       case MxL_IF_36_15_MHZ:
+               val = 0x0a;
+               break;
+       case MxL_IF_44_MHZ:
+               val = 0x0b;
+               break;
+       default:
+               mxl_fail(-EINVAL);
+               return;
+       }
+       set_reg_bits(state->tab_init, 0x02, 0x0f, val);
+
+       /* set inverted IF or normal IF */
+       set_reg_bits(state->tab_init, 0x02, 0x10, invert_if ? 0x10 : 0x00);
+
+       state->if_freq = if_freq;
+
+       return;
+}
+
+static void mxl5007t_set_xtal_freq_bits(struct mxl5007t_state *state,
+                                       enum mxl5007t_xtal_freq xtal_freq)
+{
+       switch (xtal_freq) {
+       case MxL_XTAL_16_MHZ:
+               /* select xtal freq & ref freq */
+               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x00);
+               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x00);
+               break;
+       case MxL_XTAL_20_MHZ:
+               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x10);
+               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x01);
+               break;
+       case MxL_XTAL_20_25_MHZ:
+               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x20);
+               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x02);
+               break;
+       case MxL_XTAL_20_48_MHZ:
+               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x30);
+               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x03);
+               break;
+       case MxL_XTAL_24_MHZ:
+               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x40);
+               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x04);
+               break;
+       case MxL_XTAL_25_MHZ:
+               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x50);
+               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x05);
+               break;
+       case MxL_XTAL_25_14_MHZ:
+               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x60);
+               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x06);
+               break;
+       case MxL_XTAL_27_MHZ:
+               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x70);
+               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x07);
+               break;
+       case MxL_XTAL_28_8_MHZ:
+               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x80);
+               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x08);
+               break;
+       case MxL_XTAL_32_MHZ:
+               set_reg_bits(state->tab_init, 0x03, 0xf0, 0x90);
+               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x09);
+               break;
+       case MxL_XTAL_40_MHZ:
+               set_reg_bits(state->tab_init, 0x03, 0xf0, 0xa0);
+               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0a);
+               break;
+       case MxL_XTAL_44_MHZ:
+               set_reg_bits(state->tab_init, 0x03, 0xf0, 0xb0);
+               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0b);
+               break;
+       case MxL_XTAL_48_MHZ:
+               set_reg_bits(state->tab_init, 0x03, 0xf0, 0xc0);
+               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0c);
+               break;
+       case MxL_XTAL_49_3811_MHZ:
+               set_reg_bits(state->tab_init, 0x03, 0xf0, 0xd0);
+               set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0d);
+               break;
+       default:
+               mxl_fail(-EINVAL);
+               return;
+       }
+
+       return;
+}
+
+static struct reg_pair_t *mxl5007t_calc_init_regs(struct mxl5007t_state *state,
+                                                 enum mxl5007t_mode mode)
+{
+       struct mxl5007t_config *cfg = state->config;
+
+       memcpy(&state->tab_init, &init_tab, sizeof(init_tab));
+       memcpy(&state->tab_init_cable, &init_tab_cable, sizeof(init_tab_cable));
+
+       mxl5007t_set_mode_bits(state, mode, cfg->if_diff_out_level);
+       mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if);
+       mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz);
+
+       set_reg_bits(state->tab_init, 0x04, 0x01, cfg->loop_thru_enable);
+       set_reg_bits(state->tab_init, 0x03, 0x08, cfg->clk_out_enable << 3);
+       set_reg_bits(state->tab_init, 0x03, 0x07, cfg->clk_out_amp);
+
+       if (mode >= MxL_MODE_CABLE) {
+               copy_reg_bits(state->tab_init, state->tab_init_cable);
+               return state->tab_init_cable;
+       } else
+               return state->tab_init;
+}
+
+/* ------------------------------------------------------------------------- */
+
+enum mxl5007t_bw_mhz {
+       MxL_BW_6MHz = 6,
+       MxL_BW_7MHz = 7,
+       MxL_BW_8MHz = 8,
+};
+
+static void mxl5007t_set_bw_bits(struct mxl5007t_state *state,
+                                enum mxl5007t_bw_mhz bw)
+{
+       u8 val;
+
+       switch (bw) {
+       case MxL_BW_6MHz:
+               val = 0x15; /* set DIG_MODEINDEX, DIG_MODEINDEX_A,
+                            * and DIG_MODEINDEX_CSF */
+               break;
+       case MxL_BW_7MHz:
+               val = 0x2a;
+               break;
+       case MxL_BW_8MHz:
+               val = 0x3f;
+               break;
+       default:
+               mxl_fail(-EINVAL);
+               return;
+       }
+       set_reg_bits(state->tab_rftune, 0x0c, 0x3f, val);
+
+       return;
+}
+
+static struct
+reg_pair_t *mxl5007t_calc_rf_tune_regs(struct mxl5007t_state *state,
+                                      u32 rf_freq, enum mxl5007t_bw_mhz bw)
+{
+       u32 dig_rf_freq = 0;
+       u32 temp;
+       u32 frac_divider = 1000000;
+       unsigned int i;
+
+       memcpy(&state->tab_rftune, &reg_pair_rftune, sizeof(reg_pair_rftune));
+
+       mxl5007t_set_bw_bits(state, bw);
+
+       /* Convert RF frequency into 16 bits =>
+        * 10 bit integer (MHz) + 6 bit fraction */
+       dig_rf_freq = rf_freq / MHz;
+
+       temp = rf_freq % MHz;
+
+       for (i = 0; i < 6; i++) {
+               dig_rf_freq <<= 1;
+               frac_divider /= 2;
+               if (temp > frac_divider) {
+                       temp -= frac_divider;
+                       dig_rf_freq++;
+               }
+       }
+
+       /* add to have shift center point by 7.8124 kHz */
+       if (temp > 7812)
+               dig_rf_freq++;
+
+       set_reg_bits(state->tab_rftune, 0x0d, 0xff, (u8) dig_rf_freq);
+       set_reg_bits(state->tab_rftune, 0x0e, 0xff, (u8) (dig_rf_freq >> 8));
+
+       if (rf_freq >= 333000000)
+               set_reg_bits(state->tab_rftune, 0x80, 0x40, 0x40);
+
+       return state->tab_rftune;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl5007t_write_reg(struct mxl5007t_state *state, u8 reg, u8 val)
+{
+       u8 buf[] = { reg, val };
+       struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0,
+                              .buf = buf, .len = 2 };
+       int ret;
+
+       ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
+       if (ret != 1) {
+               mxl_err("failed!");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int mxl5007t_write_regs(struct mxl5007t_state *state,
+                              struct reg_pair_t *reg_pair)
+{
+       unsigned int i = 0;
+       int ret = 0;
+
+       while ((ret == 0) && (reg_pair[i].reg || reg_pair[i].val)) {
+               ret = mxl5007t_write_reg(state,
+                                        reg_pair[i].reg, reg_pair[i].val);
+               i++;
+       }
+       return ret;
+}
+
+static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val)
+{
+       u8 buf[2] = { 0xfb, reg };
+       struct i2c_msg msg[] = {
+               { .addr = state->i2c_props.addr, .flags = 0,
+                 .buf = buf, .len = 2 },
+               { .addr = state->i2c_props.addr, .flags = I2C_M_RD,
+                 .buf = val, .len = 1 },
+       };
+       int ret;
+
+       ret = i2c_transfer(state->i2c_props.adap, msg, 2);
+       if (ret != 2) {
+               mxl_err("failed!");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int mxl5007t_soft_reset(struct mxl5007t_state *state)
+{
+       u8 d = 0xff;
+       struct i2c_msg msg = {
+               .addr = state->i2c_props.addr, .flags = 0,
+               .buf = &d, .len = 1
+       };
+       int ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
+
+       if (ret != 1) {
+               mxl_err("failed!");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int mxl5007t_tuner_init(struct mxl5007t_state *state,
+                              enum mxl5007t_mode mode)
+{
+       struct reg_pair_t *init_regs;
+       int ret;
+
+       ret = mxl5007t_soft_reset(state);
+       if (mxl_fail(ret))
+               goto fail;
+
+       /* calculate initialization reg array */
+       init_regs = mxl5007t_calc_init_regs(state, mode);
+
+       ret = mxl5007t_write_regs(state, init_regs);
+       if (mxl_fail(ret))
+               goto fail;
+       mdelay(1);
+fail:
+       return ret;
+}
+
+static int mxl5007t_tuner_rf_tune(struct mxl5007t_state *state, u32 rf_freq_hz,
+                                 enum mxl5007t_bw_mhz bw)
+{
+       struct reg_pair_t *rf_tune_regs;
+       int ret;
+
+       /* calculate channel change reg array */
+       rf_tune_regs = mxl5007t_calc_rf_tune_regs(state, rf_freq_hz, bw);
+
+       ret = mxl5007t_write_regs(state, rf_tune_regs);
+       if (mxl_fail(ret))
+               goto fail;
+       msleep(3);
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl5007t_synth_lock_status(struct mxl5007t_state *state,
+                                     int *rf_locked, int *ref_locked)
+{
+       u8 d;
+       int ret;
+
+       *rf_locked = 0;
+       *ref_locked = 0;
+
+       ret = mxl5007t_read_reg(state, 0xd8, &d);
+       if (mxl_fail(ret))
+               goto fail;
+
+       if ((d & 0x0c) == 0x0c)
+               *rf_locked = 1;
+
+       if ((d & 0x03) == 0x03)
+               *ref_locked = 1;
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
+{
+       struct mxl5007t_state *state = fe->tuner_priv;
+       int rf_locked, ref_locked, ret;
+
+       *status = 0;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       ret = mxl5007t_synth_lock_status(state, &rf_locked, &ref_locked);
+       if (mxl_fail(ret))
+               goto fail;
+       mxl_debug("%s%s", rf_locked ? "rf locked " : "",
+                 ref_locked ? "ref locked" : "");
+
+       if ((rf_locked) || (ref_locked))
+               *status |= TUNER_STATUS_LOCKED;
+fail:
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       return ret;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl5007t_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u32 delsys = c->delivery_system;
+       struct mxl5007t_state *state = fe->tuner_priv;
+       enum mxl5007t_bw_mhz bw;
+       enum mxl5007t_mode mode;
+       int ret;
+       u32 freq = c->frequency;
+
+       switch (delsys) {
+       case SYS_ATSC:
+               mode = MxL_MODE_ATSC;
+               bw = MxL_BW_6MHz;
+               break;
+       case SYS_DVBC_ANNEX_B:
+               mode = MxL_MODE_CABLE;
+               bw = MxL_BW_6MHz;
+               break;
+       case SYS_DVBT:
+       case SYS_DVBT2:
+               mode = MxL_MODE_DVBT;
+               switch (c->bandwidth_hz) {
+               case 6000000:
+                       bw = MxL_BW_6MHz;
+                       break;
+               case 7000000:
+                       bw = MxL_BW_7MHz;
+                       break;
+               case 8000000:
+                       bw = MxL_BW_8MHz;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               break;
+       default:
+               mxl_err("modulation type not supported!");
+               return -EINVAL;
+       }
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       mutex_lock(&state->lock);
+
+       ret = mxl5007t_tuner_init(state, mode);
+       if (mxl_fail(ret))
+               goto fail;
+
+       ret = mxl5007t_tuner_rf_tune(state, freq, bw);
+       if (mxl_fail(ret))
+               goto fail;
+
+       state->frequency = freq;
+       state->bandwidth = c->bandwidth_hz;
+fail:
+       mutex_unlock(&state->lock);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       return ret;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl5007t_init(struct dvb_frontend *fe)
+{
+       struct mxl5007t_state *state = fe->tuner_priv;
+       int ret;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       /* wake from standby */
+       ret = mxl5007t_write_reg(state, 0x01, 0x01);
+       mxl_fail(ret);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       return ret;
+}
+
+static int mxl5007t_sleep(struct dvb_frontend *fe)
+{
+       struct mxl5007t_state *state = fe->tuner_priv;
+       int ret;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       /* enter standby mode */
+       ret = mxl5007t_write_reg(state, 0x01, 0x00);
+       mxl_fail(ret);
+       ret = mxl5007t_write_reg(state, 0x0f, 0x00);
+       mxl_fail(ret);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       return ret;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int mxl5007t_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct mxl5007t_state *state = fe->tuner_priv;
+       *frequency = state->frequency;
+       return 0;
+}
+
+static int mxl5007t_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct mxl5007t_state *state = fe->tuner_priv;
+       *bandwidth = state->bandwidth;
+       return 0;
+}
+
+static int mxl5007t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct mxl5007t_state *state = fe->tuner_priv;
+
+       *frequency = 0;
+
+       switch (state->if_freq) {
+       case MxL_IF_4_MHZ:
+               *frequency = 4000000;
+               break;
+       case MxL_IF_4_5_MHZ:
+               *frequency = 4500000;
+               break;
+       case MxL_IF_4_57_MHZ:
+               *frequency = 4570000;
+               break;
+       case MxL_IF_5_MHZ:
+               *frequency = 5000000;
+               break;
+       case MxL_IF_5_38_MHZ:
+               *frequency = 5380000;
+               break;
+       case MxL_IF_6_MHZ:
+               *frequency = 6000000;
+               break;
+       case MxL_IF_6_28_MHZ:
+               *frequency = 6280000;
+               break;
+       case MxL_IF_9_1915_MHZ:
+               *frequency = 9191500;
+               break;
+       case MxL_IF_35_25_MHZ:
+               *frequency = 35250000;
+               break;
+       case MxL_IF_36_15_MHZ:
+               *frequency = 36150000;
+               break;
+       case MxL_IF_44_MHZ:
+               *frequency = 44000000;
+               break;
+       }
+       return 0;
+}
+
+static int mxl5007t_release(struct dvb_frontend *fe)
+{
+       struct mxl5007t_state *state = fe->tuner_priv;
+
+       mutex_lock(&mxl5007t_list_mutex);
+
+       if (state)
+               hybrid_tuner_release_state(state);
+
+       mutex_unlock(&mxl5007t_list_mutex);
+
+       fe->tuner_priv = NULL;
+
+       return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static struct dvb_tuner_ops mxl5007t_tuner_ops = {
+       .info = {
+               .name = "MaxLinear MxL5007T",
+       },
+       .init              = mxl5007t_init,
+       .sleep             = mxl5007t_sleep,
+       .set_params        = mxl5007t_set_params,
+       .get_status        = mxl5007t_get_status,
+       .get_frequency     = mxl5007t_get_frequency,
+       .get_bandwidth     = mxl5007t_get_bandwidth,
+       .release           = mxl5007t_release,
+       .get_if_frequency  = mxl5007t_get_if_frequency,
+};
+
+static int mxl5007t_get_chip_id(struct mxl5007t_state *state)
+{
+       char *name;
+       int ret;
+       u8 id;
+
+       ret = mxl5007t_read_reg(state, 0xd9, &id);
+       if (mxl_fail(ret))
+               goto fail;
+
+       switch (id) {
+       case MxL_5007_V1_F1:
+               name = "MxL5007.v1.f1";
+               break;
+       case MxL_5007_V1_F2:
+               name = "MxL5007.v1.f2";
+               break;
+       case MxL_5007_V2_100_F1:
+               name = "MxL5007.v2.100.f1";
+               break;
+       case MxL_5007_V2_100_F2:
+               name = "MxL5007.v2.100.f2";
+               break;
+       case MxL_5007_V2_200_F1:
+               name = "MxL5007.v2.200.f1";
+               break;
+       case MxL_5007_V2_200_F2:
+               name = "MxL5007.v2.200.f2";
+               break;
+       case MxL_5007_V4:
+               name = "MxL5007T.v4";
+               break;
+       default:
+               name = "MxL5007T";
+               printk(KERN_WARNING "%s: unknown rev (%02x)\n", __func__, id);
+               id = MxL_UNKNOWN_ID;
+       }
+       state->chip_id = id;
+       mxl_info("%s detected @ %d-%04x", name,
+                i2c_adapter_id(state->i2c_props.adap),
+                state->i2c_props.addr);
+       return 0;
+fail:
+       mxl_warn("unable to identify device @ %d-%04x",
+                i2c_adapter_id(state->i2c_props.adap),
+                state->i2c_props.addr);
+
+       state->chip_id = MxL_UNKNOWN_ID;
+       return ret;
+}
+
+struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
+                                    struct i2c_adapter *i2c, u8 addr,
+                                    struct mxl5007t_config *cfg)
+{
+       struct mxl5007t_state *state = NULL;
+       int instance, ret;
+
+       mutex_lock(&mxl5007t_list_mutex);
+       instance = hybrid_tuner_request_state(struct mxl5007t_state, state,
+                                             hybrid_tuner_instance_list,
+                                             i2c, addr, "mxl5007t");
+       switch (instance) {
+       case 0:
+               goto fail;
+       case 1:
+               /* new tuner instance */
+               state->config = cfg;
+
+               mutex_init(&state->lock);
+
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+
+               ret = mxl5007t_get_chip_id(state);
+
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+
+               /* check return value of mxl5007t_get_chip_id */
+               if (mxl_fail(ret))
+                       goto fail;
+               break;
+       default:
+               /* existing tuner instance */
+               break;
+       }
+       fe->tuner_priv = state;
+       mutex_unlock(&mxl5007t_list_mutex);
+
+       memcpy(&fe->ops.tuner_ops, &mxl5007t_tuner_ops,
+              sizeof(struct dvb_tuner_ops));
+
+       return fe;
+fail:
+       mutex_unlock(&mxl5007t_list_mutex);
+
+       mxl5007t_release(fe);
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(mxl5007t_attach);
+MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver");
+MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.2");
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/tuners/mxl5007t.h b/drivers/media/tuners/mxl5007t.h
new file mode 100644 (file)
index 0000000..aa3eea0
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ *  mxl5007t.h - driver for the MaxLinear MxL5007T silicon tuner
+ *
+ *  Copyright (C) 2008 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ *  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 __MXL5007T_H__
+#define __MXL5007T_H__
+
+#include "dvb_frontend.h"
+
+/* ------------------------------------------------------------------------- */
+
+enum mxl5007t_if_freq {
+       MxL_IF_4_MHZ,      /*  4000000 */
+       MxL_IF_4_5_MHZ,    /*  4500000 */
+       MxL_IF_4_57_MHZ,   /*  4570000 */
+       MxL_IF_5_MHZ,      /*  5000000 */
+       MxL_IF_5_38_MHZ,   /*  5380000 */
+       MxL_IF_6_MHZ,      /*  6000000 */
+       MxL_IF_6_28_MHZ,   /*  6280000 */
+       MxL_IF_9_1915_MHZ, /*  9191500 */
+       MxL_IF_35_25_MHZ,  /* 35250000 */
+       MxL_IF_36_15_MHZ,  /* 36150000 */
+       MxL_IF_44_MHZ,     /* 44000000 */
+};
+
+enum mxl5007t_xtal_freq {
+       MxL_XTAL_16_MHZ,      /* 16000000 */
+       MxL_XTAL_20_MHZ,      /* 20000000 */
+       MxL_XTAL_20_25_MHZ,   /* 20250000 */
+       MxL_XTAL_20_48_MHZ,   /* 20480000 */
+       MxL_XTAL_24_MHZ,      /* 24000000 */
+       MxL_XTAL_25_MHZ,      /* 25000000 */
+       MxL_XTAL_25_14_MHZ,   /* 25140000 */
+       MxL_XTAL_27_MHZ,      /* 27000000 */
+       MxL_XTAL_28_8_MHZ,    /* 28800000 */
+       MxL_XTAL_32_MHZ,      /* 32000000 */
+       MxL_XTAL_40_MHZ,      /* 40000000 */
+       MxL_XTAL_44_MHZ,      /* 44000000 */
+       MxL_XTAL_48_MHZ,      /* 48000000 */
+       MxL_XTAL_49_3811_MHZ, /* 49381100 */
+};
+
+enum mxl5007t_clkout_amp {
+       MxL_CLKOUT_AMP_0_94V = 0,
+       MxL_CLKOUT_AMP_0_53V = 1,
+       MxL_CLKOUT_AMP_0_37V = 2,
+       MxL_CLKOUT_AMP_0_28V = 3,
+       MxL_CLKOUT_AMP_0_23V = 4,
+       MxL_CLKOUT_AMP_0_20V = 5,
+       MxL_CLKOUT_AMP_0_17V = 6,
+       MxL_CLKOUT_AMP_0_15V = 7,
+};
+
+struct mxl5007t_config {
+       s32 if_diff_out_level;
+       enum mxl5007t_clkout_amp clk_out_amp;
+       enum mxl5007t_xtal_freq xtal_freq_hz;
+       enum mxl5007t_if_freq if_freq_hz;
+       unsigned int invert_if:1;
+       unsigned int loop_thru_enable:1;
+       unsigned int clk_out_enable:1;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_MXL5007T) || (defined(CONFIG_MEDIA_TUNER_MXL5007T_MODULE) && defined(MODULE))
+extern struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
+                                           struct i2c_adapter *i2c, u8 addr,
+                                           struct mxl5007t_config *cfg);
+#else
+static inline struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
+                                                  struct i2c_adapter *i2c,
+                                                  u8 addr,
+                                                  struct mxl5007t_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* __MXL5007T_H__ */
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
+
diff --git a/drivers/media/tuners/qt1010.c b/drivers/media/tuners/qt1010.c
new file mode 100644 (file)
index 0000000..bdc39e1
--- /dev/null
@@ -0,0 +1,480 @@
+/*
+ *  Driver for Quantek QT1010 silicon tuner
+ *
+ *  Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
+ *                     Aapo Tahkola <aet@rasterburn.org>
+ *
+ *  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.
+ */
+#include "qt1010.h"
+#include "qt1010_priv.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+#define dprintk(args...) \
+       do { \
+               if (debug) printk(KERN_DEBUG "QT1010: " args); \
+       } while (0)
+
+/* read single register */
+static int qt1010_readreg(struct qt1010_priv *priv, u8 reg, u8 *val)
+{
+       struct i2c_msg msg[2] = {
+               { .addr = priv->cfg->i2c_address,
+                 .flags = 0, .buf = &reg, .len = 1 },
+               { .addr = priv->cfg->i2c_address,
+                 .flags = I2C_M_RD, .buf = val, .len = 1 },
+       };
+
+       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
+               printk(KERN_WARNING "qt1010 I2C read failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+/* write single register */
+static int qt1010_writereg(struct qt1010_priv *priv, u8 reg, u8 val)
+{
+       u8 buf[2] = { reg, val };
+       struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
+                              .flags = 0, .buf = buf, .len = 2 };
+
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "qt1010 I2C write failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+/* dump all registers */
+static void qt1010_dump_regs(struct qt1010_priv *priv)
+{
+       u8 reg, val;
+
+       for (reg = 0; ; reg++) {
+               if (reg % 16 == 0) {
+                       if (reg)
+                               printk(KERN_CONT "\n");
+                       printk(KERN_DEBUG "%02x:", reg);
+               }
+               if (qt1010_readreg(priv, reg, &val) == 0)
+                       printk(KERN_CONT " %02x", val);
+               else
+                       printk(KERN_CONT " --");
+               if (reg == 0x2f)
+                       break;
+       }
+       printk(KERN_CONT "\n");
+}
+
+static int qt1010_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct qt1010_priv *priv;
+       int err;
+       u32 freq, div, mod1, mod2;
+       u8 i, tmpval, reg05;
+       qt1010_i2c_oper_t rd[48] = {
+               { QT1010_WR, 0x01, 0x80 },
+               { QT1010_WR, 0x02, 0x3f },
+               { QT1010_WR, 0x05, 0xff }, /* 02 c write */
+               { QT1010_WR, 0x06, 0x44 },
+               { QT1010_WR, 0x07, 0xff }, /* 04 c write */
+               { QT1010_WR, 0x08, 0x08 },
+               { QT1010_WR, 0x09, 0xff }, /* 06 c write */
+               { QT1010_WR, 0x0a, 0xff }, /* 07 c write */
+               { QT1010_WR, 0x0b, 0xff }, /* 08 c write */
+               { QT1010_WR, 0x0c, 0xe1 },
+               { QT1010_WR, 0x1a, 0xff }, /* 10 c write */
+               { QT1010_WR, 0x1b, 0x00 },
+               { QT1010_WR, 0x1c, 0x89 },
+               { QT1010_WR, 0x11, 0xff }, /* 13 c write */
+               { QT1010_WR, 0x12, 0xff }, /* 14 c write */
+               { QT1010_WR, 0x22, 0xff }, /* 15 c write */
+               { QT1010_WR, 0x1e, 0x00 },
+               { QT1010_WR, 0x1e, 0xd0 },
+               { QT1010_RD, 0x22, 0xff }, /* 16 c read */
+               { QT1010_WR, 0x1e, 0x00 },
+               { QT1010_RD, 0x05, 0xff }, /* 20 c read */
+               { QT1010_RD, 0x22, 0xff }, /* 21 c read */
+               { QT1010_WR, 0x23, 0xd0 },
+               { QT1010_WR, 0x1e, 0x00 },
+               { QT1010_WR, 0x1e, 0xe0 },
+               { QT1010_RD, 0x23, 0xff }, /* 25 c read */
+               { QT1010_RD, 0x23, 0xff }, /* 26 c read */
+               { QT1010_WR, 0x1e, 0x00 },
+               { QT1010_WR, 0x24, 0xd0 },
+               { QT1010_WR, 0x1e, 0x00 },
+               { QT1010_WR, 0x1e, 0xf0 },
+               { QT1010_RD, 0x24, 0xff }, /* 31 c read */
+               { QT1010_WR, 0x1e, 0x00 },
+               { QT1010_WR, 0x14, 0x7f },
+               { QT1010_WR, 0x15, 0x7f },
+               { QT1010_WR, 0x05, 0xff }, /* 35 c write */
+               { QT1010_WR, 0x06, 0x00 },
+               { QT1010_WR, 0x15, 0x1f },
+               { QT1010_WR, 0x16, 0xff },
+               { QT1010_WR, 0x18, 0xff },
+               { QT1010_WR, 0x1f, 0xff }, /* 40 c write */
+               { QT1010_WR, 0x20, 0xff }, /* 41 c write */
+               { QT1010_WR, 0x21, 0x53 },
+               { QT1010_WR, 0x25, 0xff }, /* 43 c write */
+               { QT1010_WR, 0x26, 0x15 },
+               { QT1010_WR, 0x00, 0xff }, /* 45 c write */
+               { QT1010_WR, 0x02, 0x00 },
+               { QT1010_WR, 0x01, 0x00 }
+       };
+
+#define FREQ1 32000000 /* 32 MHz */
+#define FREQ2  4000000 /* 4 MHz Quartz oscillator in the stick? */
+
+       priv = fe->tuner_priv;
+       freq = c->frequency;
+       div = (freq + QT1010_OFFSET) / QT1010_STEP;
+       freq = (div * QT1010_STEP) - QT1010_OFFSET;
+       mod1 = (freq + QT1010_OFFSET) % FREQ1;
+       mod2 = (freq + QT1010_OFFSET) % FREQ2;
+       priv->frequency = freq;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+       /* reg 05 base value */
+       if      (freq < 290000000) reg05 = 0x14; /* 290 MHz */
+       else if (freq < 610000000) reg05 = 0x34; /* 610 MHz */
+       else if (freq < 802000000) reg05 = 0x54; /* 802 MHz */
+       else                       reg05 = 0x74;
+
+       /* 0x5 */
+       rd[2].val = reg05;
+
+       /* 07 - set frequency: 32 MHz scale */
+       rd[4].val = (freq + QT1010_OFFSET) / FREQ1;
+
+       /* 09 - changes every 8/24 MHz */
+       if (mod1 < 8000000) rd[6].val = 0x1d;
+       else                rd[6].val = 0x1c;
+
+       /* 0a - set frequency: 4 MHz scale (max 28 MHz) */
+       if      (mod1 < 1*FREQ2) rd[7].val = 0x09; /*  +0 MHz */
+       else if (mod1 < 2*FREQ2) rd[7].val = 0x08; /*  +4 MHz */
+       else if (mod1 < 3*FREQ2) rd[7].val = 0x0f; /*  +8 MHz */
+       else if (mod1 < 4*FREQ2) rd[7].val = 0x0e; /* +12 MHz */
+       else if (mod1 < 5*FREQ2) rd[7].val = 0x0d; /* +16 MHz */
+       else if (mod1 < 6*FREQ2) rd[7].val = 0x0c; /* +20 MHz */
+       else if (mod1 < 7*FREQ2) rd[7].val = 0x0b; /* +24 MHz */
+       else                     rd[7].val = 0x0a; /* +28 MHz */
+
+       /* 0b - changes every 2/2 MHz */
+       if (mod2 < 2000000) rd[8].val = 0x45;
+       else                rd[8].val = 0x44;
+
+       /* 1a - set frequency: 125 kHz scale (max 3875 kHz)*/
+       tmpval = 0x78; /* byte, overflows intentionally */
+       rd[10].val = tmpval-((mod2/QT1010_STEP)*0x08);
+
+       /* 11 */
+       rd[13].val = 0xfd; /* TODO: correct value calculation */
+
+       /* 12 */
+       rd[14].val = 0x91; /* TODO: correct value calculation */
+
+       /* 22 */
+       if      (freq < 450000000) rd[15].val = 0xd0; /* 450 MHz */
+       else if (freq < 482000000) rd[15].val = 0xd1; /* 482 MHz */
+       else if (freq < 514000000) rd[15].val = 0xd4; /* 514 MHz */
+       else if (freq < 546000000) rd[15].val = 0xd7; /* 546 MHz */
+       else if (freq < 610000000) rd[15].val = 0xda; /* 610 MHz */
+       else                       rd[15].val = 0xd0;
+
+       /* 05 */
+       rd[35].val = (reg05 & 0xf0);
+
+       /* 1f */
+       if      (mod1 <  8000000) tmpval = 0x00;
+       else if (mod1 < 12000000) tmpval = 0x01;
+       else if (mod1 < 16000000) tmpval = 0x02;
+       else if (mod1 < 24000000) tmpval = 0x03;
+       else if (mod1 < 28000000) tmpval = 0x04;
+       else                      tmpval = 0x05;
+       rd[40].val = (priv->reg1f_init_val + 0x0e + tmpval);
+
+       /* 20 */
+       if      (mod1 <  8000000) tmpval = 0x00;
+       else if (mod1 < 12000000) tmpval = 0x01;
+       else if (mod1 < 20000000) tmpval = 0x02;
+       else if (mod1 < 24000000) tmpval = 0x03;
+       else if (mod1 < 28000000) tmpval = 0x04;
+       else                      tmpval = 0x05;
+       rd[41].val = (priv->reg20_init_val + 0x0d + tmpval);
+
+       /* 25 */
+       rd[43].val = priv->reg25_init_val;
+
+       /* 00 */
+       rd[45].val = 0x92; /* TODO: correct value calculation */
+
+       dprintk("freq:%u 05:%02x 07:%02x 09:%02x 0a:%02x 0b:%02x " \
+               "1a:%02x 11:%02x 12:%02x 22:%02x 05:%02x 1f:%02x " \
+               "20:%02x 25:%02x 00:%02x", \
+               freq, rd[2].val, rd[4].val, rd[6].val, rd[7].val, rd[8].val, \
+               rd[10].val, rd[13].val, rd[14].val, rd[15].val, rd[35].val, \
+               rd[40].val, rd[41].val, rd[43].val, rd[45].val);
+
+       for (i = 0; i < ARRAY_SIZE(rd); i++) {
+               if (rd[i].oper == QT1010_WR) {
+                       err = qt1010_writereg(priv, rd[i].reg, rd[i].val);
+               } else { /* read is required to proper locking */
+                       err = qt1010_readreg(priv, rd[i].reg, &tmpval);
+               }
+               if (err) return err;
+       }
+
+       if (debug)
+               qt1010_dump_regs(priv);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+       return 0;
+}
+
+static int qt1010_init_meas1(struct qt1010_priv *priv,
+                            u8 oper, u8 reg, u8 reg_init_val, u8 *retval)
+{
+       u8 i, val1, val2;
+       int err;
+
+       qt1010_i2c_oper_t i2c_data[] = {
+               { QT1010_WR, reg, reg_init_val },
+               { QT1010_WR, 0x1e, 0x00 },
+               { QT1010_WR, 0x1e, oper },
+               { QT1010_RD, reg, 0xff }
+       };
+
+       for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
+               if (i2c_data[i].oper == QT1010_WR) {
+                       err = qt1010_writereg(priv, i2c_data[i].reg,
+                                             i2c_data[i].val);
+               } else {
+                       err = qt1010_readreg(priv, i2c_data[i].reg, &val2);
+               }
+               if (err) return err;
+       }
+
+       do {
+               val1 = val2;
+               err = qt1010_readreg(priv, reg, &val2);
+               if (err) return err;
+               dprintk("compare reg:%02x %02x %02x", reg, val1, val2);
+       } while (val1 != val2);
+       *retval = val1;
+
+       return qt1010_writereg(priv, 0x1e, 0x00);
+}
+
+static int qt1010_init_meas2(struct qt1010_priv *priv,
+                           u8 reg_init_val, u8 *retval)
+{
+       u8 i, val;
+       int err;
+       qt1010_i2c_oper_t i2c_data[] = {
+               { QT1010_WR, 0x07, reg_init_val },
+               { QT1010_WR, 0x22, 0xd0 },
+               { QT1010_WR, 0x1e, 0x00 },
+               { QT1010_WR, 0x1e, 0xd0 },
+               { QT1010_RD, 0x22, 0xff },
+               { QT1010_WR, 0x1e, 0x00 },
+               { QT1010_WR, 0x22, 0xff }
+       };
+       for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
+               if (i2c_data[i].oper == QT1010_WR) {
+                       err = qt1010_writereg(priv, i2c_data[i].reg,
+                                             i2c_data[i].val);
+               } else {
+                       err = qt1010_readreg(priv, i2c_data[i].reg, &val);
+               }
+               if (err) return err;
+       }
+       *retval = val;
+       return 0;
+}
+
+static int qt1010_init(struct dvb_frontend *fe)
+{
+       struct qt1010_priv *priv = fe->tuner_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int err = 0;
+       u8 i, tmpval, *valptr = NULL;
+
+       qt1010_i2c_oper_t i2c_data[] = {
+               { QT1010_WR, 0x01, 0x80 },
+               { QT1010_WR, 0x0d, 0x84 },
+               { QT1010_WR, 0x0e, 0xb7 },
+               { QT1010_WR, 0x2a, 0x23 },
+               { QT1010_WR, 0x2c, 0xdc },
+               { QT1010_M1, 0x25, 0x40 }, /* get reg 25 init value */
+               { QT1010_M1, 0x81, 0xff }, /* get reg 25 init value */
+               { QT1010_WR, 0x2b, 0x70 },
+               { QT1010_WR, 0x2a, 0x23 },
+               { QT1010_M1, 0x26, 0x08 },
+               { QT1010_M1, 0x82, 0xff },
+               { QT1010_WR, 0x05, 0x14 },
+               { QT1010_WR, 0x06, 0x44 },
+               { QT1010_WR, 0x07, 0x28 },
+               { QT1010_WR, 0x08, 0x0b },
+               { QT1010_WR, 0x11, 0xfd },
+               { QT1010_M1, 0x22, 0x0d },
+               { QT1010_M1, 0xd0, 0xff },
+               { QT1010_WR, 0x06, 0x40 },
+               { QT1010_WR, 0x16, 0xf0 },
+               { QT1010_WR, 0x02, 0x38 },
+               { QT1010_WR, 0x03, 0x18 },
+               { QT1010_WR, 0x20, 0xe0 },
+               { QT1010_M1, 0x1f, 0x20 }, /* get reg 1f init value */
+               { QT1010_M1, 0x84, 0xff }, /* get reg 1f init value */
+               { QT1010_RD, 0x20, 0x20 }, /* get reg 20 init value */
+               { QT1010_WR, 0x03, 0x19 },
+               { QT1010_WR, 0x02, 0x3f },
+               { QT1010_WR, 0x21, 0x53 },
+               { QT1010_RD, 0x21, 0xff },
+               { QT1010_WR, 0x11, 0xfd },
+               { QT1010_WR, 0x05, 0x34 },
+               { QT1010_WR, 0x06, 0x44 },
+               { QT1010_WR, 0x08, 0x08 }
+       };
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+       for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
+               switch (i2c_data[i].oper) {
+               case QT1010_WR:
+                       err = qt1010_writereg(priv, i2c_data[i].reg,
+                                             i2c_data[i].val);
+                       break;
+               case QT1010_RD:
+                       if (i2c_data[i].val == 0x20)
+                               valptr = &priv->reg20_init_val;
+                       else
+                               valptr = &tmpval;
+                       err = qt1010_readreg(priv, i2c_data[i].reg, valptr);
+                       break;
+               case QT1010_M1:
+                       if (i2c_data[i].val == 0x25)
+                               valptr = &priv->reg25_init_val;
+                       else if (i2c_data[i].val == 0x1f)
+                               valptr = &priv->reg1f_init_val;
+                       else
+                               valptr = &tmpval;
+                       err = qt1010_init_meas1(priv, i2c_data[i+1].reg,
+                                               i2c_data[i].reg,
+                                               i2c_data[i].val, valptr);
+                       i++;
+                       break;
+               }
+               if (err) return err;
+       }
+
+       for (i = 0x31; i < 0x3a; i++) /* 0x31 - 0x39 */
+               if ((err = qt1010_init_meas2(priv, i, &tmpval)))
+                       return err;
+
+       c->frequency = 545000000; /* Sigmatek DVB-110 545000000 */
+                                     /* MSI Megasky 580 GL861 533000000 */
+       return qt1010_set_params(fe);
+}
+
+static int qt1010_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static int qt1010_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct qt1010_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static int qt1010_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       *frequency = 36125000;
+       return 0;
+}
+
+static const struct dvb_tuner_ops qt1010_tuner_ops = {
+       .info = {
+               .name           = "Quantek QT1010",
+               .frequency_min  = QT1010_MIN_FREQ,
+               .frequency_max  = QT1010_MAX_FREQ,
+               .frequency_step = QT1010_STEP,
+       },
+
+       .release       = qt1010_release,
+       .init          = qt1010_init,
+       /* TODO: implement sleep */
+
+       .set_params    = qt1010_set_params,
+       .get_frequency = qt1010_get_frequency,
+       .get_if_frequency = qt1010_get_if_frequency,
+};
+
+struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe,
+                                   struct i2c_adapter *i2c,
+                                   struct qt1010_config *cfg)
+{
+       struct qt1010_priv *priv = NULL;
+       u8 id;
+
+       priv = kzalloc(sizeof(struct qt1010_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->cfg = cfg;
+       priv->i2c = i2c;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+
+       /* Try to detect tuner chip. Probably this is not correct register. */
+       if (qt1010_readreg(priv, 0x29, &id) != 0 || (id != 0x39)) {
+               kfree(priv);
+               return NULL;
+       }
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+       printk(KERN_INFO "Quantek QT1010 successfully identified.\n");
+       memcpy(&fe->ops.tuner_ops, &qt1010_tuner_ops,
+              sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = priv;
+       return fe;
+}
+EXPORT_SYMBOL(qt1010_attach);
+
+MODULE_DESCRIPTION("Quantek QT1010 silicon tuner driver");
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>");
+MODULE_VERSION("0.1");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/qt1010.h b/drivers/media/tuners/qt1010.h
new file mode 100644 (file)
index 0000000..807fb7b
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *  Driver for Quantek QT1010 silicon tuner
+ *
+ *  Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
+ *                     Aapo Tahkola <aet@rasterburn.org>
+ *
+ *  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 QT1010_H
+#define QT1010_H
+
+#include "dvb_frontend.h"
+
+struct qt1010_config {
+       u8 i2c_address;
+};
+
+/**
+ * Attach a qt1010 tuner to the supplied frontend structure.
+ *
+ * @param fe   frontend to attach to
+ * @param i2c  i2c adapter to use
+ * @param cfg  tuner hw based configuration
+ * @return fe  pointer on success, NULL on failure
+ */
+#if defined(CONFIG_MEDIA_TUNER_QT1010) || (defined(CONFIG_MEDIA_TUNER_QT1010_MODULE) && defined(MODULE))
+extern struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe,
+                                         struct i2c_adapter *i2c,
+                                         struct qt1010_config *cfg);
+#else
+static inline struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe,
+                                                struct i2c_adapter *i2c,
+                                                struct qt1010_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_MEDIA_TUNER_QT1010
+
+#endif
diff --git a/drivers/media/tuners/qt1010_priv.h b/drivers/media/tuners/qt1010_priv.h
new file mode 100644 (file)
index 0000000..2c42d3f
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ *  Driver for Quantek QT1010 silicon tuner
+ *
+ *  Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
+ *                     Aapo Tahkola <aet@rasterburn.org>
+ *
+ *  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 QT1010_PRIV_H
+#define QT1010_PRIV_H
+
+/*
+reg def meaning
+=== === =======
+00  00  ?
+01  a0  ? operation start/stop; start=80, stop=00
+02  00  ?
+03  19  ?
+04  00  ?
+05  00  ? maybe band selection
+06  00  ?
+07  2b  set frequency: 32 MHz scale, n*32 MHz
+08  0b  ?
+09  10  ? changes every 8/24 MHz; values 1d/1c
+0a  08  set frequency: 4 MHz scale, n*4 MHz
+0b  41  ? changes every 2/2 MHz; values 45/45
+0c  e1  ?
+0d  94  ?
+0e  b6  ?
+0f  2c  ?
+10  10  ?
+11  f1  ? maybe device specified adjustment
+12  11  ? maybe device specified adjustment
+13  3f  ?
+14  1f  ?
+15  3f  ?
+16  ff  ?
+17  ff  ?
+18  f7  ?
+19  80  ?
+1a  d0  set frequency: 125 kHz scale, n*125 kHz
+1b  00  ?
+1c  89  ?
+1d  00  ?
+1e  00  ? looks like operation register; write cmd here, read result from 1f-26
+1f  20  ? chip initialization
+20  e0  ? chip initialization
+21  20  ?
+22  d0  ?
+23  d0  ?
+24  d0  ?
+25  40  ? chip initialization
+26  08  ?
+27  29  ?
+28  55  ?
+29  39  ?
+2a  13  ?
+2b  01  ?
+2c  ea  ?
+2d  00  ?
+2e  00  ? not used?
+2f  00  ? not used?
+*/
+
+#define QT1010_STEP         125000 /*  125 kHz used by Windows drivers,
+                                     hw could be more precise but we don't
+                                     know how to use */
+#define QT1010_MIN_FREQ   48000000 /*   48 MHz */
+#define QT1010_MAX_FREQ  860000000 /*  860 MHz */
+#define QT1010_OFFSET   1246000000 /* 1246 MHz */
+
+#define QT1010_WR 0
+#define QT1010_RD 1
+#define QT1010_M1 3
+
+typedef struct {
+       u8 oper, reg, val;
+} qt1010_i2c_oper_t;
+
+struct qt1010_priv {
+       struct qt1010_config *cfg;
+       struct i2c_adapter   *i2c;
+
+       u8 reg1f_init_val;
+       u8 reg20_init_val;
+       u8 reg25_init_val;
+
+       u32 frequency;
+};
+
+#endif
diff --git a/drivers/media/tuners/tda18212.c b/drivers/media/tuners/tda18212.c
new file mode 100644 (file)
index 0000000..5d9f028
--- /dev/null
@@ -0,0 +1,319 @@
+/*
+ * NXP TDA18212HN silicon tuner driver
+ *
+ * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "tda18212.h"
+
+struct tda18212_priv {
+       struct tda18212_config *cfg;
+       struct i2c_adapter *i2c;
+
+       u32 if_frequency;
+};
+
+/* write multiple registers */
+static int tda18212_wr_regs(struct tda18212_priv *priv, u8 reg, u8 *val,
+       int len)
+{
+       int ret;
+       u8 buf[len+1];
+       struct i2c_msg msg[1] = {
+               {
+                       .addr = priv->cfg->i2c_address,
+                       .flags = 0,
+                       .len = sizeof(buf),
+                       .buf = buf,
+               }
+       };
+
+       buf[0] = reg;
+       memcpy(&buf[1], val, len);
+
+       ret = i2c_transfer(priv->i2c, msg, 1);
+       if (ret == 1) {
+               ret = 0;
+       } else {
+               dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
+                               "len=%d\n", KBUILD_MODNAME, ret, reg, len);
+               ret = -EREMOTEIO;
+       }
+       return ret;
+}
+
+/* read multiple registers */
+static int tda18212_rd_regs(struct tda18212_priv *priv, u8 reg, u8 *val,
+       int len)
+{
+       int ret;
+       u8 buf[len];
+       struct i2c_msg msg[2] = {
+               {
+                       .addr = priv->cfg->i2c_address,
+                       .flags = 0,
+                       .len = 1,
+                       .buf = &reg,
+               }, {
+                       .addr = priv->cfg->i2c_address,
+                       .flags = I2C_M_RD,
+                       .len = sizeof(buf),
+                       .buf = buf,
+               }
+       };
+
+       ret = i2c_transfer(priv->i2c, msg, 2);
+       if (ret == 2) {
+               memcpy(val, buf, len);
+               ret = 0;
+       } else {
+               dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
+                               "len=%d\n", KBUILD_MODNAME, ret, reg, len);
+               ret = -EREMOTEIO;
+       }
+
+       return ret;
+}
+
+/* write single register */
+static int tda18212_wr_reg(struct tda18212_priv *priv, u8 reg, u8 val)
+{
+       return tda18212_wr_regs(priv, reg, &val, 1);
+}
+
+/* read single register */
+static int tda18212_rd_reg(struct tda18212_priv *priv, u8 reg, u8 *val)
+{
+       return tda18212_rd_regs(priv, reg, val, 1);
+}
+
+#if 0 /* keep, useful when developing driver */
+static void tda18212_dump_regs(struct tda18212_priv *priv)
+{
+       int i;
+       u8 buf[256];
+
+       #define TDA18212_RD_LEN 32
+       for (i = 0; i < sizeof(buf); i += TDA18212_RD_LEN)
+               tda18212_rd_regs(priv, i, &buf[i], TDA18212_RD_LEN);
+
+       print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 32, 1, buf,
+               sizeof(buf), true);
+
+       return;
+}
+#endif
+
+static int tda18212_set_params(struct dvb_frontend *fe)
+{
+       struct tda18212_priv *priv = fe->tuner_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret, i;
+       u32 if_khz;
+       u8 buf[9];
+       #define DVBT_6   0
+       #define DVBT_7   1
+       #define DVBT_8   2
+       #define DVBT2_6  3
+       #define DVBT2_7  4
+       #define DVBT2_8  5
+       #define DVBC_6   6
+       #define DVBC_8   7
+       static const u8 bw_params[][3] = {
+                    /* reg:   0f    13    23 */
+               [DVBT_6]  = { 0xb3, 0x20, 0x03 },
+               [DVBT_7]  = { 0xb3, 0x31, 0x01 },
+               [DVBT_8]  = { 0xb3, 0x22, 0x01 },
+               [DVBT2_6] = { 0xbc, 0x20, 0x03 },
+               [DVBT2_7] = { 0xbc, 0x72, 0x03 },
+               [DVBT2_8] = { 0xbc, 0x22, 0x01 },
+               [DVBC_6]  = { 0x92, 0x50, 0x03 },
+               [DVBC_8]  = { 0x92, 0x53, 0x03 },
+       };
+
+       dev_dbg(&priv->i2c->dev,
+                       "%s: delivery_system=%d frequency=%d bandwidth_hz=%d\n",
+                       __func__, c->delivery_system, c->frequency,
+                       c->bandwidth_hz);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+       switch (c->delivery_system) {
+       case SYS_DVBT:
+               switch (c->bandwidth_hz) {
+               case 6000000:
+                       if_khz = priv->cfg->if_dvbt_6;
+                       i = DVBT_6;
+                       break;
+               case 7000000:
+                       if_khz = priv->cfg->if_dvbt_7;
+                       i = DVBT_7;
+                       break;
+               case 8000000:
+                       if_khz = priv->cfg->if_dvbt_8;
+                       i = DVBT_8;
+                       break;
+               default:
+                       ret = -EINVAL;
+                       goto error;
+               }
+               break;
+       case SYS_DVBT2:
+               switch (c->bandwidth_hz) {
+               case 6000000:
+                       if_khz = priv->cfg->if_dvbt2_6;
+                       i = DVBT2_6;
+                       break;
+               case 7000000:
+                       if_khz = priv->cfg->if_dvbt2_7;
+                       i = DVBT2_7;
+                       break;
+               case 8000000:
+                       if_khz = priv->cfg->if_dvbt2_8;
+                       i = DVBT2_8;
+                       break;
+               default:
+                       ret = -EINVAL;
+                       goto error;
+               }
+               break;
+       case SYS_DVBC_ANNEX_A:
+       case SYS_DVBC_ANNEX_C:
+               if_khz = priv->cfg->if_dvbc;
+               i = DVBC_8;
+               break;
+       default:
+               ret = -EINVAL;
+               goto error;
+       }
+
+       ret = tda18212_wr_reg(priv, 0x23, bw_params[i][2]);
+       if (ret)
+               goto error;
+
+       ret = tda18212_wr_reg(priv, 0x06, 0x00);
+       if (ret)
+               goto error;
+
+       ret = tda18212_wr_reg(priv, 0x0f, bw_params[i][0]);
+       if (ret)
+               goto error;
+
+       buf[0] = 0x02;
+       buf[1] = bw_params[i][1];
+       buf[2] = 0x03; /* default value */
+       buf[3] = DIV_ROUND_CLOSEST(if_khz, 50);
+       buf[4] = ((c->frequency / 1000) >> 16) & 0xff;
+       buf[5] = ((c->frequency / 1000) >>  8) & 0xff;
+       buf[6] = ((c->frequency / 1000) >>  0) & 0xff;
+       buf[7] = 0xc1;
+       buf[8] = 0x01;
+       ret = tda18212_wr_regs(priv, 0x12, buf, sizeof(buf));
+       if (ret)
+               goto error;
+
+       /* actual IF rounded as it is on register */
+       priv->if_frequency = buf[3] * 50 * 1000;
+
+exit:
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+
+       return ret;
+
+error:
+       dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+       goto exit;
+}
+
+static int tda18212_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct tda18212_priv *priv = fe->tuner_priv;
+
+       *frequency = priv->if_frequency;
+
+       return 0;
+}
+
+static int tda18212_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static const struct dvb_tuner_ops tda18212_tuner_ops = {
+       .info = {
+               .name           = "NXP TDA18212",
+
+               .frequency_min  =  48000000,
+               .frequency_max  = 864000000,
+               .frequency_step =      1000,
+       },
+
+       .release       = tda18212_release,
+
+       .set_params    = tda18212_set_params,
+       .get_if_frequency = tda18212_get_if_frequency,
+};
+
+struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
+       struct i2c_adapter *i2c, struct tda18212_config *cfg)
+{
+       struct tda18212_priv *priv = NULL;
+       int ret;
+       u8 uninitialized_var(val);
+
+       priv = kzalloc(sizeof(struct tda18212_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->cfg = cfg;
+       priv->i2c = i2c;
+       fe->tuner_priv = priv;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+       /* check if the tuner is there */
+       ret = tda18212_rd_reg(priv, 0x00, &val);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+
+       dev_dbg(&priv->i2c->dev, "%s: ret=%d chip id=%02x\n", __func__, ret,
+                       val);
+       if (ret || val != 0xc7) {
+               kfree(priv);
+               return NULL;
+       }
+
+       dev_info(&priv->i2c->dev,
+                       "%s: NXP TDA18212HN successfully identified\n",
+                       KBUILD_MODNAME);
+
+       memcpy(&fe->ops.tuner_ops, &tda18212_tuner_ops,
+               sizeof(struct dvb_tuner_ops));
+
+       return fe;
+}
+EXPORT_SYMBOL(tda18212_attach);
+
+MODULE_DESCRIPTION("NXP TDA18212HN silicon tuner driver");
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/tda18212.h b/drivers/media/tuners/tda18212.h
new file mode 100644 (file)
index 0000000..9bd5da4
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * NXP TDA18212HN silicon tuner driver
+ *
+ * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef TDA18212_H
+#define TDA18212_H
+
+#include "dvb_frontend.h"
+
+struct tda18212_config {
+       u8 i2c_address;
+
+       u16 if_dvbt_6;
+       u16 if_dvbt_7;
+       u16 if_dvbt_8;
+       u16 if_dvbt2_5;
+       u16 if_dvbt2_6;
+       u16 if_dvbt2_7;
+       u16 if_dvbt2_8;
+       u16 if_dvbc;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_TDA18212) || \
+       (defined(CONFIG_MEDIA_TUNER_TDA18212_MODULE) && defined(MODULE))
+extern struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
+       struct i2c_adapter *i2c, struct tda18212_config *cfg);
+#else
+static inline struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
+       struct i2c_adapter *i2c, struct tda18212_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/tuners/tda18218.c b/drivers/media/tuners/tda18218.c
new file mode 100644 (file)
index 0000000..8a6f9ca
--- /dev/null
@@ -0,0 +1,342 @@
+/*
+ * NXP TDA18218HN silicon tuner driver
+ *
+ * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.
+ */
+
+#include "tda18218.h"
+#include "tda18218_priv.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+/* write multiple registers */
+static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
+{
+       int ret = 0;
+       u8 buf[1+len], quotient, remainder, i, msg_len, msg_len_max;
+       struct i2c_msg msg[1] = {
+               {
+                       .addr = priv->cfg->i2c_address,
+                       .flags = 0,
+                       .buf = buf,
+               }
+       };
+
+       msg_len_max = priv->cfg->i2c_wr_max - 1;
+       quotient = len / msg_len_max;
+       remainder = len % msg_len_max;
+       msg_len = msg_len_max;
+       for (i = 0; (i <= quotient && remainder); i++) {
+               if (i == quotient)  /* set len of the last msg */
+                       msg_len = remainder;
+
+               msg[0].len = msg_len + 1;
+               buf[0] = reg + i * msg_len_max;
+               memcpy(&buf[1], &val[i * msg_len_max], msg_len);
+
+               ret = i2c_transfer(priv->i2c, msg, 1);
+               if (ret != 1)
+                       break;
+       }
+
+       if (ret == 1) {
+               ret = 0;
+       } else {
+               warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len);
+               ret = -EREMOTEIO;
+       }
+
+       return ret;
+}
+
+/* read multiple registers */
+static int tda18218_rd_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
+{
+       int ret;
+       u8 buf[reg+len]; /* we must start read always from reg 0x00 */
+       struct i2c_msg msg[2] = {
+               {
+                       .addr = priv->cfg->i2c_address,
+                       .flags = 0,
+                       .len = 1,
+                       .buf = "\x00",
+               }, {
+                       .addr = priv->cfg->i2c_address,
+                       .flags = I2C_M_RD,
+                       .len = sizeof(buf),
+                       .buf = buf,
+               }
+       };
+
+       ret = i2c_transfer(priv->i2c, msg, 2);
+       if (ret == 2) {
+               memcpy(val, &buf[reg], len);
+               ret = 0;
+       } else {
+               warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len);
+               ret = -EREMOTEIO;
+       }
+
+       return ret;
+}
+
+/* write single register */
+static int tda18218_wr_reg(struct tda18218_priv *priv, u8 reg, u8 val)
+{
+       return tda18218_wr_regs(priv, reg, &val, 1);
+}
+
+/* read single register */
+
+static int tda18218_rd_reg(struct tda18218_priv *priv, u8 reg, u8 *val)
+{
+       return tda18218_rd_regs(priv, reg, val, 1);
+}
+
+static int tda18218_set_params(struct dvb_frontend *fe)
+{
+       struct tda18218_priv *priv = fe->tuner_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u32 bw = c->bandwidth_hz;
+       int ret;
+       u8 buf[3], i, BP_Filter, LP_Fc;
+       u32 LO_Frac;
+       /* TODO: find out correct AGC algorithm */
+       u8 agc[][2] = {
+               { R20_AGC11, 0x60 },
+               { R23_AGC21, 0x02 },
+               { R20_AGC11, 0xa0 },
+               { R23_AGC21, 0x09 },
+               { R20_AGC11, 0xe0 },
+               { R23_AGC21, 0x0c },
+               { R20_AGC11, 0x40 },
+               { R23_AGC21, 0x01 },
+               { R20_AGC11, 0x80 },
+               { R23_AGC21, 0x08 },
+               { R20_AGC11, 0xc0 },
+               { R23_AGC21, 0x0b },
+               { R24_AGC22, 0x1c },
+               { R24_AGC22, 0x0c },
+       };
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+       /* low-pass filter cut-off frequency */
+       if (bw <= 6000000) {
+               LP_Fc = 0;
+               priv->if_frequency = 3000000;
+       } else if (bw <= 7000000) {
+               LP_Fc = 1;
+               priv->if_frequency = 3500000;
+       } else {
+               LP_Fc = 2;
+               priv->if_frequency = 4000000;
+       }
+
+       LO_Frac = c->frequency + priv->if_frequency;
+
+       /* band-pass filter */
+       if (LO_Frac < 188000000)
+               BP_Filter = 3;
+       else if (LO_Frac < 253000000)
+               BP_Filter = 4;
+       else if (LO_Frac < 343000000)
+               BP_Filter = 5;
+       else
+               BP_Filter = 6;
+
+       buf[0] = (priv->regs[R1A_IF1] & ~7) | BP_Filter; /* BP_Filter */
+       buf[1] = (priv->regs[R1B_IF2] & ~3) | LP_Fc; /* LP_Fc */
+       buf[2] = priv->regs[R1C_AGC2B];
+       ret = tda18218_wr_regs(priv, R1A_IF1, buf, 3);
+       if (ret)
+               goto error;
+
+       buf[0] = (LO_Frac / 1000) >> 12; /* LO_Frac_0 */
+       buf[1] = (LO_Frac / 1000) >> 4; /* LO_Frac_1 */
+       buf[2] = (LO_Frac / 1000) << 4 |
+               (priv->regs[R0C_MD5] & 0x0f); /* LO_Frac_2 */
+       ret = tda18218_wr_regs(priv, R0A_MD3, buf, 3);
+       if (ret)
+               goto error;
+
+       buf[0] = priv->regs[R0F_MD8] | (1 << 6); /* Freq_prog_Start */
+       ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
+       if (ret)
+               goto error;
+
+       buf[0] = priv->regs[R0F_MD8] & ~(1 << 6); /* Freq_prog_Start */
+       ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
+       if (ret)
+               goto error;
+
+       /* trigger AGC */
+       for (i = 0; i < ARRAY_SIZE(agc); i++) {
+               ret = tda18218_wr_reg(priv, agc[i][0], agc[i][1]);
+               if (ret)
+                       goto error;
+       }
+
+error:
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+
+       if (ret)
+               dbg("%s: failed ret:%d", __func__, ret);
+
+       return ret;
+}
+
+static int tda18218_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct tda18218_priv *priv = fe->tuner_priv;
+       *frequency = priv->if_frequency;
+       dbg("%s: if=%d", __func__, *frequency);
+       return 0;
+}
+
+static int tda18218_sleep(struct dvb_frontend *fe)
+{
+       struct tda18218_priv *priv = fe->tuner_priv;
+       int ret;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+       /* standby */
+       ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+
+       if (ret)
+               dbg("%s: failed ret:%d", __func__, ret);
+
+       return ret;
+}
+
+static int tda18218_init(struct dvb_frontend *fe)
+{
+       struct tda18218_priv *priv = fe->tuner_priv;
+       int ret;
+
+       /* TODO: calibrations */
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+       ret = tda18218_wr_regs(priv, R00_ID, priv->regs, TDA18218_NUM_REGS);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+
+       if (ret)
+               dbg("%s: failed ret:%d", __func__, ret);
+
+       return ret;
+}
+
+static int tda18218_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static const struct dvb_tuner_ops tda18218_tuner_ops = {
+       .info = {
+               .name           = "NXP TDA18218",
+
+               .frequency_min  = 174000000,
+               .frequency_max  = 864000000,
+               .frequency_step =      1000,
+       },
+
+       .release       = tda18218_release,
+       .init          = tda18218_init,
+       .sleep         = tda18218_sleep,
+
+       .set_params    = tda18218_set_params,
+
+       .get_if_frequency = tda18218_get_if_frequency,
+};
+
+struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
+       struct i2c_adapter *i2c, struct tda18218_config *cfg)
+{
+       struct tda18218_priv *priv = NULL;
+       u8 uninitialized_var(val);
+       int ret;
+       /* chip default registers values */
+       static u8 def_regs[] = {
+               0xc0, 0x88, 0x00, 0x8e, 0x03, 0x00, 0x00, 0xd0, 0x00, 0x40,
+               0x00, 0x00, 0x07, 0xff, 0x84, 0x09, 0x00, 0x13, 0x00, 0x00,
+               0x01, 0x84, 0x09, 0xf0, 0x19, 0x0a, 0x8e, 0x69, 0x98, 0x01,
+               0x00, 0x58, 0x10, 0x40, 0x8c, 0x00, 0x0c, 0x48, 0x85, 0xc9,
+               0xa7, 0x00, 0x00, 0x00, 0x30, 0x81, 0x80, 0x00, 0x39, 0x00,
+               0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xf6
+       };
+
+       priv = kzalloc(sizeof(struct tda18218_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->cfg = cfg;
+       priv->i2c = i2c;
+       fe->tuner_priv = priv;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+       /* check if the tuner is there */
+       ret = tda18218_rd_reg(priv, R00_ID, &val);
+       dbg("%s: ret:%d chip ID:%02x", __func__, ret, val);
+       if (ret || val != def_regs[R00_ID]) {
+               kfree(priv);
+               return NULL;
+       }
+
+       info("NXP TDA18218HN successfully identified.");
+
+       memcpy(&fe->ops.tuner_ops, &tda18218_tuner_ops,
+               sizeof(struct dvb_tuner_ops));
+       memcpy(priv->regs, def_regs, sizeof(def_regs));
+
+       /* loop-through enabled chip default register values */
+       if (priv->cfg->loop_through) {
+               priv->regs[R17_PD1] = 0xb0;
+               priv->regs[R18_PD2] = 0x59;
+       }
+
+       /* standby */
+       ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
+       if (ret)
+               dbg("%s: failed ret:%d", __func__, ret);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+
+       return fe;
+}
+EXPORT_SYMBOL(tda18218_attach);
+
+MODULE_DESCRIPTION("NXP TDA18218HN silicon tuner driver");
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/tda18218.h b/drivers/media/tuners/tda18218.h
new file mode 100644 (file)
index 0000000..b4180d1
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * NXP TDA18218HN silicon tuner driver
+ *
+ * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
+ *
+ *    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 TDA18218_H
+#define TDA18218_H
+
+#include "dvb_frontend.h"
+
+struct tda18218_config {
+       u8 i2c_address;
+       u8 i2c_wr_max;
+       u8 loop_through:1;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_TDA18218) || \
+       (defined(CONFIG_MEDIA_TUNER_TDA18218_MODULE) && defined(MODULE))
+extern struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
+       struct i2c_adapter *i2c, struct tda18218_config *cfg);
+#else
+static inline struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
+       struct i2c_adapter *i2c, struct tda18218_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/tuners/tda18218_priv.h b/drivers/media/tuners/tda18218_priv.h
new file mode 100644 (file)
index 0000000..dc52b72
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * NXP TDA18218HN silicon tuner driver
+ *
+ * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
+ *
+ *    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 TDA18218_PRIV_H
+#define TDA18218_PRIV_H
+
+#define LOG_PREFIX "tda18218"
+
+#undef dbg
+#define dbg(f, arg...) \
+       if (debug) \
+               printk(KERN_DEBUG   LOG_PREFIX": " f "\n" , ## arg)
+#undef err
+#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
+#undef info
+#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
+#undef warn
+#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
+
+#define R00_ID         0x00    /* ID byte */
+#define R01_R1         0x01    /* Read byte 1 */
+#define R02_R2         0x02    /* Read byte 2 */
+#define R03_R3         0x03    /* Read byte 3 */
+#define R04_R4         0x04    /* Read byte 4 */
+#define R05_R5         0x05    /* Read byte 5 */
+#define R06_R6         0x06    /* Read byte 6 */
+#define R07_MD1        0x07    /* Main divider byte 1 */
+#define R08_PSM1       0x08    /* PSM byte 1 */
+#define R09_MD2        0x09    /* Main divider byte 2 */
+#define R0A_MD3        0x0a    /* Main divider byte 1 */
+#define R0B_MD4        0x0b    /* Main divider byte 4 */
+#define R0C_MD5        0x0c    /* Main divider byte 5 */
+#define R0D_MD6        0x0d    /* Main divider byte 6 */
+#define R0E_MD7        0x0e    /* Main divider byte 7 */
+#define R0F_MD8        0x0f    /* Main divider byte 8 */
+#define R10_CD1        0x10    /* Call divider byte 1 */
+#define R11_CD2        0x11    /* Call divider byte 2 */
+#define R12_CD3        0x12    /* Call divider byte 3 */
+#define R13_CD4        0x13    /* Call divider byte 4 */
+#define R14_CD5        0x14    /* Call divider byte 5 */
+#define R15_CD6        0x15    /* Call divider byte 6 */
+#define R16_CD7        0x16    /* Call divider byte 7 */
+#define R17_PD1        0x17    /* Power-down byte 1 */
+#define R18_PD2        0x18    /* Power-down byte 2 */
+#define R19_XTOUT      0x19    /* XTOUT byte */
+#define R1A_IF1        0x1a    /* IF byte 1 */
+#define R1B_IF2        0x1b    /* IF byte 2 */
+#define R1C_AGC2B      0x1c    /* AGC2b byte */
+#define R1D_PSM2       0x1d    /* PSM byte 2 */
+#define R1E_PSM3       0x1e    /* PSM byte 3 */
+#define R1F_PSM4       0x1f    /* PSM byte 4 */
+#define R20_AGC11      0x20    /* AGC1 byte 1 */
+#define R21_AGC12      0x21    /* AGC1 byte 2 */
+#define R22_AGC13      0x22    /* AGC1 byte 3 */
+#define R23_AGC21      0x23    /* AGC2 byte 1 */
+#define R24_AGC22      0x24    /* AGC2 byte 2 */
+#define R25_AAGC       0x25    /* Analog AGC byte */
+#define R26_RC         0x26    /* RC byte */
+#define R27_RSSI       0x27    /* RSSI byte */
+#define R28_IRCAL1     0x28    /* IR CAL byte 1 */
+#define R29_IRCAL2     0x29    /* IR CAL byte 2 */
+#define R2A_IRCAL3     0x2a    /* IR CAL byte 3 */
+#define R2B_IRCAL4     0x2b    /* IR CAL byte 4 */
+#define R2C_RFCAL1     0x2c    /* RF CAL byte 1 */
+#define R2D_RFCAL2     0x2d    /* RF CAL byte 2 */
+#define R2E_RFCAL3     0x2e    /* RF CAL byte 3 */
+#define R2F_RFCAL4     0x2f    /* RF CAL byte 4 */
+#define R30_RFCAL5     0x30    /* RF CAL byte 5 */
+#define R31_RFCAL6     0x31    /* RF CAL byte 6 */
+#define R32_RFCAL7     0x32    /* RF CAL byte 7 */
+#define R33_RFCAL8     0x33    /* RF CAL byte 8 */
+#define R34_RFCAL9     0x34    /* RF CAL byte 9 */
+#define R35_RFCAL10    0x35    /* RF CAL byte 10 */
+#define R36_RFCALRAM1  0x36    /* RF CAL RAM byte 1 */
+#define R37_RFCALRAM2  0x37    /* RF CAL RAM byte 2 */
+#define R38_MARGIN     0x38    /* Margin byte */
+#define R39_FMAX1      0x39    /* Fmax byte 1 */
+#define R3A_FMAX2      0x3a    /* Fmax byte 2 */
+
+#define TDA18218_NUM_REGS 59
+
+struct tda18218_priv {
+       struct tda18218_config *cfg;
+       struct i2c_adapter *i2c;
+
+       u32 if_frequency;
+
+       u8 regs[TDA18218_NUM_REGS];
+};
+
+#endif
diff --git a/drivers/media/tuners/tda18271-common.c b/drivers/media/tuners/tda18271-common.c
new file mode 100644 (file)
index 0000000..39c6457
--- /dev/null
@@ -0,0 +1,703 @@
+/*
+    tda18271-common.c - driver for the Philips / NXP TDA18271 silicon tuner
+
+    Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
+
+    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.
+*/
+
+#include "tda18271-priv.h"
+
+static int tda18271_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       enum tda18271_i2c_gate gate;
+       int ret = 0;
+
+       switch (priv->gate) {
+       case TDA18271_GATE_DIGITAL:
+       case TDA18271_GATE_ANALOG:
+               gate = priv->gate;
+               break;
+       case TDA18271_GATE_AUTO:
+       default:
+               switch (priv->mode) {
+               case TDA18271_DIGITAL:
+                       gate = TDA18271_GATE_DIGITAL;
+                       break;
+               case TDA18271_ANALOG:
+               default:
+                       gate = TDA18271_GATE_ANALOG;
+                       break;
+               }
+       }
+
+       switch (gate) {
+       case TDA18271_GATE_ANALOG:
+               if (fe->ops.analog_ops.i2c_gate_ctrl)
+                       ret = fe->ops.analog_ops.i2c_gate_ctrl(fe, enable);
+               break;
+       case TDA18271_GATE_DIGITAL:
+               if (fe->ops.i2c_gate_ctrl)
+                       ret = fe->ops.i2c_gate_ctrl(fe, enable);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+       return ret;
+};
+
+/*---------------------------------------------------------------------*/
+
+static void tda18271_dump_regs(struct dvb_frontend *fe, int extended)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+
+       tda_reg("=== TDA18271 REG DUMP ===\n");
+       tda_reg("ID_BYTE            = 0x%02x\n", 0xff & regs[R_ID]);
+       tda_reg("THERMO_BYTE        = 0x%02x\n", 0xff & regs[R_TM]);
+       tda_reg("POWER_LEVEL_BYTE   = 0x%02x\n", 0xff & regs[R_PL]);
+       tda_reg("EASY_PROG_BYTE_1   = 0x%02x\n", 0xff & regs[R_EP1]);
+       tda_reg("EASY_PROG_BYTE_2   = 0x%02x\n", 0xff & regs[R_EP2]);
+       tda_reg("EASY_PROG_BYTE_3   = 0x%02x\n", 0xff & regs[R_EP3]);
+       tda_reg("EASY_PROG_BYTE_4   = 0x%02x\n", 0xff & regs[R_EP4]);
+       tda_reg("EASY_PROG_BYTE_5   = 0x%02x\n", 0xff & regs[R_EP5]);
+       tda_reg("CAL_POST_DIV_BYTE  = 0x%02x\n", 0xff & regs[R_CPD]);
+       tda_reg("CAL_DIV_BYTE_1     = 0x%02x\n", 0xff & regs[R_CD1]);
+       tda_reg("CAL_DIV_BYTE_2     = 0x%02x\n", 0xff & regs[R_CD2]);
+       tda_reg("CAL_DIV_BYTE_3     = 0x%02x\n", 0xff & regs[R_CD3]);
+       tda_reg("MAIN_POST_DIV_BYTE = 0x%02x\n", 0xff & regs[R_MPD]);
+       tda_reg("MAIN_DIV_BYTE_1    = 0x%02x\n", 0xff & regs[R_MD1]);
+       tda_reg("MAIN_DIV_BYTE_2    = 0x%02x\n", 0xff & regs[R_MD2]);
+       tda_reg("MAIN_DIV_BYTE_3    = 0x%02x\n", 0xff & regs[R_MD3]);
+
+       /* only dump extended regs if DBG_ADV is set */
+       if (!(tda18271_debug & DBG_ADV))
+               return;
+
+       /* W indicates write-only registers.
+        * Register dump for write-only registers shows last value written. */
+
+       tda_reg("EXTENDED_BYTE_1    = 0x%02x\n", 0xff & regs[R_EB1]);
+       tda_reg("EXTENDED_BYTE_2    = 0x%02x\n", 0xff & regs[R_EB2]);
+       tda_reg("EXTENDED_BYTE_3    = 0x%02x\n", 0xff & regs[R_EB3]);
+       tda_reg("EXTENDED_BYTE_4    = 0x%02x\n", 0xff & regs[R_EB4]);
+       tda_reg("EXTENDED_BYTE_5    = 0x%02x\n", 0xff & regs[R_EB5]);
+       tda_reg("EXTENDED_BYTE_6    = 0x%02x\n", 0xff & regs[R_EB6]);
+       tda_reg("EXTENDED_BYTE_7    = 0x%02x\n", 0xff & regs[R_EB7]);
+       tda_reg("EXTENDED_BYTE_8    = 0x%02x\n", 0xff & regs[R_EB8]);
+       tda_reg("EXTENDED_BYTE_9  W = 0x%02x\n", 0xff & regs[R_EB9]);
+       tda_reg("EXTENDED_BYTE_10   = 0x%02x\n", 0xff & regs[R_EB10]);
+       tda_reg("EXTENDED_BYTE_11   = 0x%02x\n", 0xff & regs[R_EB11]);
+       tda_reg("EXTENDED_BYTE_12   = 0x%02x\n", 0xff & regs[R_EB12]);
+       tda_reg("EXTENDED_BYTE_13   = 0x%02x\n", 0xff & regs[R_EB13]);
+       tda_reg("EXTENDED_BYTE_14   = 0x%02x\n", 0xff & regs[R_EB14]);
+       tda_reg("EXTENDED_BYTE_15   = 0x%02x\n", 0xff & regs[R_EB15]);
+       tda_reg("EXTENDED_BYTE_16 W = 0x%02x\n", 0xff & regs[R_EB16]);
+       tda_reg("EXTENDED_BYTE_17 W = 0x%02x\n", 0xff & regs[R_EB17]);
+       tda_reg("EXTENDED_BYTE_18   = 0x%02x\n", 0xff & regs[R_EB18]);
+       tda_reg("EXTENDED_BYTE_19 W = 0x%02x\n", 0xff & regs[R_EB19]);
+       tda_reg("EXTENDED_BYTE_20 W = 0x%02x\n", 0xff & regs[R_EB20]);
+       tda_reg("EXTENDED_BYTE_21   = 0x%02x\n", 0xff & regs[R_EB21]);
+       tda_reg("EXTENDED_BYTE_22   = 0x%02x\n", 0xff & regs[R_EB22]);
+       tda_reg("EXTENDED_BYTE_23   = 0x%02x\n", 0xff & regs[R_EB23]);
+}
+
+int tda18271_read_regs(struct dvb_frontend *fe)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       unsigned char buf = 0x00;
+       int ret;
+       struct i2c_msg msg[] = {
+               { .addr = priv->i2c_props.addr, .flags = 0,
+                 .buf = &buf, .len = 1 },
+               { .addr = priv->i2c_props.addr, .flags = I2C_M_RD,
+                 .buf = regs, .len = 16 }
+       };
+
+       tda18271_i2c_gate_ctrl(fe, 1);
+
+       /* read all registers */
+       ret = i2c_transfer(priv->i2c_props.adap, msg, 2);
+
+       tda18271_i2c_gate_ctrl(fe, 0);
+
+       if (ret != 2)
+               tda_err("ERROR: i2c_transfer returned: %d\n", ret);
+
+       if (tda18271_debug & DBG_REG)
+               tda18271_dump_regs(fe, 0);
+
+       return (ret == 2 ? 0 : ret);
+}
+
+int tda18271_read_extended(struct dvb_frontend *fe)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       unsigned char regdump[TDA18271_NUM_REGS];
+       unsigned char buf = 0x00;
+       int ret, i;
+       struct i2c_msg msg[] = {
+               { .addr = priv->i2c_props.addr, .flags = 0,
+                 .buf = &buf, .len = 1 },
+               { .addr = priv->i2c_props.addr, .flags = I2C_M_RD,
+                 .buf = regdump, .len = TDA18271_NUM_REGS }
+       };
+
+       tda18271_i2c_gate_ctrl(fe, 1);
+
+       /* read all registers */
+       ret = i2c_transfer(priv->i2c_props.adap, msg, 2);
+
+       tda18271_i2c_gate_ctrl(fe, 0);
+
+       if (ret != 2)
+               tda_err("ERROR: i2c_transfer returned: %d\n", ret);
+
+       for (i = 0; i < TDA18271_NUM_REGS; i++) {
+               /* don't update write-only registers */
+               if ((i != R_EB9)  &&
+                   (i != R_EB16) &&
+                   (i != R_EB17) &&
+                   (i != R_EB19) &&
+                   (i != R_EB20))
+               regs[i] = regdump[i];
+       }
+
+       if (tda18271_debug & DBG_REG)
+               tda18271_dump_regs(fe, 1);
+
+       return (ret == 2 ? 0 : ret);
+}
+
+int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       unsigned char buf[TDA18271_NUM_REGS + 1];
+       struct i2c_msg msg = { .addr = priv->i2c_props.addr, .flags = 0,
+                              .buf = buf };
+       int i, ret = 1, max;
+
+       BUG_ON((len == 0) || (idx + len > sizeof(buf)));
+
+
+       switch (priv->small_i2c) {
+       case TDA18271_03_BYTE_CHUNK_INIT:
+               max = 3;
+               break;
+       case TDA18271_08_BYTE_CHUNK_INIT:
+               max = 8;
+               break;
+       case TDA18271_16_BYTE_CHUNK_INIT:
+               max = 16;
+               break;
+       case TDA18271_39_BYTE_CHUNK_INIT:
+       default:
+               max = 39;
+       }
+
+       tda18271_i2c_gate_ctrl(fe, 1);
+       while (len) {
+               if (max > len)
+                       max = len;
+
+               buf[0] = idx;
+               for (i = 1; i <= max; i++)
+                       buf[i] = regs[idx - 1 + i];
+
+               msg.len = max + 1;
+
+               /* write registers */
+               ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
+               if (ret != 1)
+                       break;
+
+               idx += max;
+               len -= max;
+       }
+       tda18271_i2c_gate_ctrl(fe, 0);
+
+       if (ret != 1)
+               tda_err("ERROR: idx = 0x%x, len = %d, "
+                       "i2c_transfer returned: %d\n", idx, max, ret);
+
+       return (ret == 1 ? 0 : ret);
+}
+
+/*---------------------------------------------------------------------*/
+
+int tda18271_charge_pump_source(struct dvb_frontend *fe,
+                               enum tda18271_pll pll, int force)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+
+       int r_cp = (pll == TDA18271_CAL_PLL) ? R_EB7 : R_EB4;
+
+       regs[r_cp] &= ~0x20;
+       regs[r_cp] |= ((force & 1) << 5);
+
+       return tda18271_write_regs(fe, r_cp, 1);
+}
+
+int tda18271_init_regs(struct dvb_frontend *fe)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+
+       tda_dbg("initializing registers for device @ %d-%04x\n",
+               i2c_adapter_id(priv->i2c_props.adap),
+               priv->i2c_props.addr);
+
+       /* initialize registers */
+       switch (priv->id) {
+       case TDA18271HDC1:
+               regs[R_ID]   = 0x83;
+               break;
+       case TDA18271HDC2:
+               regs[R_ID]   = 0x84;
+               break;
+       };
+
+       regs[R_TM]   = 0x08;
+       regs[R_PL]   = 0x80;
+       regs[R_EP1]  = 0xc6;
+       regs[R_EP2]  = 0xdf;
+       regs[R_EP3]  = 0x16;
+       regs[R_EP4]  = 0x60;
+       regs[R_EP5]  = 0x80;
+       regs[R_CPD]  = 0x80;
+       regs[R_CD1]  = 0x00;
+       regs[R_CD2]  = 0x00;
+       regs[R_CD3]  = 0x00;
+       regs[R_MPD]  = 0x00;
+       regs[R_MD1]  = 0x00;
+       regs[R_MD2]  = 0x00;
+       regs[R_MD3]  = 0x00;
+
+       switch (priv->id) {
+       case TDA18271HDC1:
+               regs[R_EB1]  = 0xff;
+               break;
+       case TDA18271HDC2:
+               regs[R_EB1]  = 0xfc;
+               break;
+       };
+
+       regs[R_EB2]  = 0x01;
+       regs[R_EB3]  = 0x84;
+       regs[R_EB4]  = 0x41;
+       regs[R_EB5]  = 0x01;
+       regs[R_EB6]  = 0x84;
+       regs[R_EB7]  = 0x40;
+       regs[R_EB8]  = 0x07;
+       regs[R_EB9]  = 0x00;
+       regs[R_EB10] = 0x00;
+       regs[R_EB11] = 0x96;
+
+       switch (priv->id) {
+       case TDA18271HDC1:
+               regs[R_EB12] = 0x0f;
+               break;
+       case TDA18271HDC2:
+               regs[R_EB12] = 0x33;
+               break;
+       };
+
+       regs[R_EB13] = 0xc1;
+       regs[R_EB14] = 0x00;
+       regs[R_EB15] = 0x8f;
+       regs[R_EB16] = 0x00;
+       regs[R_EB17] = 0x00;
+
+       switch (priv->id) {
+       case TDA18271HDC1:
+               regs[R_EB18] = 0x00;
+               break;
+       case TDA18271HDC2:
+               regs[R_EB18] = 0x8c;
+               break;
+       };
+
+       regs[R_EB19] = 0x00;
+       regs[R_EB20] = 0x20;
+
+       switch (priv->id) {
+       case TDA18271HDC1:
+               regs[R_EB21] = 0x33;
+               break;
+       case TDA18271HDC2:
+               regs[R_EB21] = 0xb3;
+               break;
+       };
+
+       regs[R_EB22] = 0x48;
+       regs[R_EB23] = 0xb0;
+
+       tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS);
+
+       /* setup agc1 gain */
+       regs[R_EB17] = 0x00;
+       tda18271_write_regs(fe, R_EB17, 1);
+       regs[R_EB17] = 0x03;
+       tda18271_write_regs(fe, R_EB17, 1);
+       regs[R_EB17] = 0x43;
+       tda18271_write_regs(fe, R_EB17, 1);
+       regs[R_EB17] = 0x4c;
+       tda18271_write_regs(fe, R_EB17, 1);
+
+       /* setup agc2 gain */
+       if ((priv->id) == TDA18271HDC1) {
+               regs[R_EB20] = 0xa0;
+               tda18271_write_regs(fe, R_EB20, 1);
+               regs[R_EB20] = 0xa7;
+               tda18271_write_regs(fe, R_EB20, 1);
+               regs[R_EB20] = 0xe7;
+               tda18271_write_regs(fe, R_EB20, 1);
+               regs[R_EB20] = 0xec;
+               tda18271_write_regs(fe, R_EB20, 1);
+       }
+
+       /* image rejection calibration */
+
+       /* low-band */
+       regs[R_EP3] = 0x1f;
+       regs[R_EP4] = 0x66;
+       regs[R_EP5] = 0x81;
+       regs[R_CPD] = 0xcc;
+       regs[R_CD1] = 0x6c;
+       regs[R_CD2] = 0x00;
+       regs[R_CD3] = 0x00;
+       regs[R_MPD] = 0xcd;
+       regs[R_MD1] = 0x77;
+       regs[R_MD2] = 0x08;
+       regs[R_MD3] = 0x00;
+
+       tda18271_write_regs(fe, R_EP3, 11);
+
+       if ((priv->id) == TDA18271HDC2) {
+               /* main pll cp source on */
+               tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 1);
+               msleep(1);
+
+               /* main pll cp source off */
+               tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 0);
+       }
+
+       msleep(5); /* pll locking */
+
+       /* launch detector */
+       tda18271_write_regs(fe, R_EP1, 1);
+       msleep(5); /* wanted low measurement */
+
+       regs[R_EP5] = 0x85;
+       regs[R_CPD] = 0xcb;
+       regs[R_CD1] = 0x66;
+       regs[R_CD2] = 0x70;
+
+       tda18271_write_regs(fe, R_EP3, 7);
+       msleep(5); /* pll locking */
+
+       /* launch optimization algorithm */
+       tda18271_write_regs(fe, R_EP2, 1);
+       msleep(30); /* image low optimization completion */
+
+       /* mid-band */
+       regs[R_EP5] = 0x82;
+       regs[R_CPD] = 0xa8;
+       regs[R_CD2] = 0x00;
+       regs[R_MPD] = 0xa9;
+       regs[R_MD1] = 0x73;
+       regs[R_MD2] = 0x1a;
+
+       tda18271_write_regs(fe, R_EP3, 11);
+       msleep(5); /* pll locking */
+
+       /* launch detector */
+       tda18271_write_regs(fe, R_EP1, 1);
+       msleep(5); /* wanted mid measurement */
+
+       regs[R_EP5] = 0x86;
+       regs[R_CPD] = 0xa8;
+       regs[R_CD1] = 0x66;
+       regs[R_CD2] = 0xa0;
+
+       tda18271_write_regs(fe, R_EP3, 7);
+       msleep(5); /* pll locking */
+
+       /* launch optimization algorithm */
+       tda18271_write_regs(fe, R_EP2, 1);
+       msleep(30); /* image mid optimization completion */
+
+       /* high-band */
+       regs[R_EP5] = 0x83;
+       regs[R_CPD] = 0x98;
+       regs[R_CD1] = 0x65;
+       regs[R_CD2] = 0x00;
+       regs[R_MPD] = 0x99;
+       regs[R_MD1] = 0x71;
+       regs[R_MD2] = 0xcd;
+
+       tda18271_write_regs(fe, R_EP3, 11);
+       msleep(5); /* pll locking */
+
+       /* launch detector */
+       tda18271_write_regs(fe, R_EP1, 1);
+       msleep(5); /* wanted high measurement */
+
+       regs[R_EP5] = 0x87;
+       regs[R_CD1] = 0x65;
+       regs[R_CD2] = 0x50;
+
+       tda18271_write_regs(fe, R_EP3, 7);
+       msleep(5); /* pll locking */
+
+       /* launch optimization algorithm */
+       tda18271_write_regs(fe, R_EP2, 1);
+       msleep(30); /* image high optimization completion */
+
+       /* return to normal mode */
+       regs[R_EP4] = 0x64;
+       tda18271_write_regs(fe, R_EP4, 1);
+
+       /* synchronize */
+       tda18271_write_regs(fe, R_EP1, 1);
+
+       return 0;
+}
+
+/*---------------------------------------------------------------------*/
+
+/*
+ *  Standby modes, EP3 [7:5]
+ *
+ *  | SM  || SM_LT || SM_XT || mode description
+ *  |=====\\=======\\=======\\===================================
+ *  |  0  ||   0   ||   0   || normal mode
+ *  |-----||-------||-------||-----------------------------------
+ *  |     ||       ||       || standby mode w/ slave tuner output
+ *  |  1  ||   0   ||   0   || & loop thru & xtal oscillator on
+ *  |-----||-------||-------||-----------------------------------
+ *  |  1  ||   1   ||   0   || standby mode w/ xtal oscillator on
+ *  |-----||-------||-------||-----------------------------------
+ *  |  1  ||   1   ||   1   || power off
+ *
+ */
+
+int tda18271_set_standby_mode(struct dvb_frontend *fe,
+                             int sm, int sm_lt, int sm_xt)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+
+       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]  |= (sm    ? (1 << 7) : 0) |
+                       (sm_lt ? (1 << 6) : 0) |
+                       (sm_xt ? (1 << 5) : 0);
+
+       return tda18271_write_regs(fe, R_EP3, 1);
+}
+
+/*---------------------------------------------------------------------*/
+
+int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq)
+{
+       /* sets main post divider & divider bytes, but does not write them */
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       u8 d, pd;
+       u32 div;
+
+       int ret = tda18271_lookup_pll_map(fe, MAIN_PLL, &freq, &pd, &d);
+       if (tda_fail(ret))
+               goto fail;
+
+       regs[R_MPD]   = (0x7f & pd);
+
+       div =  ((d * (freq / 1000)) << 7) / 125;
+
+       regs[R_MD1]   = 0x7f & (div >> 16);
+       regs[R_MD2]   = 0xff & (div >> 8);
+       regs[R_MD3]   = 0xff & div;
+fail:
+       return ret;
+}
+
+int tda18271_calc_cal_pll(struct dvb_frontend *fe, u32 freq)
+{
+       /* sets cal post divider & divider bytes, but does not write them */
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       u8 d, pd;
+       u32 div;
+
+       int ret = tda18271_lookup_pll_map(fe, CAL_PLL, &freq, &pd, &d);
+       if (tda_fail(ret))
+               goto fail;
+
+       regs[R_CPD]   = pd;
+
+       div =  ((d * (freq / 1000)) << 7) / 125;
+
+       regs[R_CD1]   = 0x7f & (div >> 16);
+       regs[R_CD2]   = 0xff & (div >> 8);
+       regs[R_CD3]   = 0xff & div;
+fail:
+       return ret;
+}
+
+/*---------------------------------------------------------------------*/
+
+int tda18271_calc_bp_filter(struct dvb_frontend *fe, u32 *freq)
+{
+       /* sets bp filter bits, but does not write them */
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       u8 val;
+
+       int ret = tda18271_lookup_map(fe, BP_FILTER, freq, &val);
+       if (tda_fail(ret))
+               goto fail;
+
+       regs[R_EP1]  &= ~0x07; /* clear bp filter bits */
+       regs[R_EP1]  |= (0x07 & val);
+fail:
+       return ret;
+}
+
+int tda18271_calc_km(struct dvb_frontend *fe, u32 *freq)
+{
+       /* sets K & M bits, but does not write them */
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       u8 val;
+
+       int ret = tda18271_lookup_map(fe, RF_CAL_KMCO, freq, &val);
+       if (tda_fail(ret))
+               goto fail;
+
+       regs[R_EB13] &= ~0x7c; /* clear k & m bits */
+       regs[R_EB13] |= (0x7c & val);
+fail:
+       return ret;
+}
+
+int tda18271_calc_rf_band(struct dvb_frontend *fe, u32 *freq)
+{
+       /* sets rf band bits, but does not write them */
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       u8 val;
+
+       int ret = tda18271_lookup_map(fe, RF_BAND, freq, &val);
+       if (tda_fail(ret))
+               goto fail;
+
+       regs[R_EP2]  &= ~0xe0; /* clear rf band bits */
+       regs[R_EP2]  |= (0xe0 & (val << 5));
+fail:
+       return ret;
+}
+
+int tda18271_calc_gain_taper(struct dvb_frontend *fe, u32 *freq)
+{
+       /* sets gain taper bits, but does not write them */
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       u8 val;
+
+       int ret = tda18271_lookup_map(fe, GAIN_TAPER, freq, &val);
+       if (tda_fail(ret))
+               goto fail;
+
+       regs[R_EP2]  &= ~0x1f; /* clear gain taper bits */
+       regs[R_EP2]  |= (0x1f & val);
+fail:
+       return ret;
+}
+
+int tda18271_calc_ir_measure(struct dvb_frontend *fe, u32 *freq)
+{
+       /* sets IR Meas bits, but does not write them */
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       u8 val;
+
+       int ret = tda18271_lookup_map(fe, IR_MEASURE, freq, &val);
+       if (tda_fail(ret))
+               goto fail;
+
+       regs[R_EP5] &= ~0x07;
+       regs[R_EP5] |= (0x07 & val);
+fail:
+       return ret;
+}
+
+int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq)
+{
+       /* sets rf cal byte (RFC_Cprog), but does not write it */
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       u8 val;
+
+       int ret = tda18271_lookup_map(fe, RF_CAL, freq, &val);
+       /* The TDA18271HD/C1 rf_cal map lookup is expected to go out of range
+        * for frequencies above 61.1 MHz.  In these cases, the internal RF
+        * tracking filters calibration mechanism is used.
+        *
+        * There is no need to warn the user about this.
+        */
+       if (ret < 0)
+               goto fail;
+
+       regs[R_EB14] = val;
+fail:
+       return ret;
+}
+
+int _tda_printk(struct tda18271_priv *state, const char *level,
+               const char *func, const char *fmt, ...)
+{
+       struct va_format vaf;
+       va_list args;
+       int rtn;
+
+       va_start(args, fmt);
+
+       vaf.fmt = fmt;
+       vaf.va = &args;
+
+       if (state)
+               rtn = printk("%s%s: [%d-%04x|%c] %pV",
+                            level, func, i2c_adapter_id(state->i2c_props.adap),
+                            state->i2c_props.addr,
+                            (state->role == TDA18271_MASTER) ? 'M' : 'S',
+                            &vaf);
+       else
+               rtn = printk("%s%s: %pV", level, func, &vaf);
+
+       va_end(args);
+
+       return rtn;
+}
diff --git a/drivers/media/tuners/tda18271-fe.c b/drivers/media/tuners/tda18271-fe.c
new file mode 100644 (file)
index 0000000..2e67f44
--- /dev/null
@@ -0,0 +1,1345 @@
+/*
+    tda18271-fe.c - driver for the Philips / NXP TDA18271 silicon tuner
+
+    Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
+
+    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.
+*/
+
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include "tda18271-priv.h"
+
+int tda18271_debug;
+module_param_named(debug, tda18271_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level "
+                "(info=1, map=2, reg=4, adv=8, cal=16 (or-able))");
+
+static int tda18271_cal_on_startup = -1;
+module_param_named(cal, tda18271_cal_on_startup, int, 0644);
+MODULE_PARM_DESC(cal, "perform RF tracking filter calibration on startup");
+
+static DEFINE_MUTEX(tda18271_list_mutex);
+static LIST_HEAD(hybrid_tuner_instance_list);
+
+/*---------------------------------------------------------------------*/
+
+static int tda18271_toggle_output(struct dvb_frontend *fe, int standby)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+
+       int ret = tda18271_set_standby_mode(fe, standby ? 1 : 0,
+                       priv->output_opt & TDA18271_OUTPUT_LT_OFF ? 1 : 0,
+                       priv->output_opt & TDA18271_OUTPUT_XT_OFF ? 1 : 0);
+
+       if (tda_fail(ret))
+               goto fail;
+
+       tda_dbg("%s mode: xtal oscillator %s, slave tuner loop thru %s\n",
+               standby ? "standby" : "active",
+               priv->output_opt & TDA18271_OUTPUT_XT_OFF ? "off" : "on",
+               priv->output_opt & TDA18271_OUTPUT_LT_OFF ? "off" : "on");
+fail:
+       return ret;
+}
+
+/*---------------------------------------------------------------------*/
+
+static inline int charge_pump_source(struct dvb_frontend *fe, int force)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       return tda18271_charge_pump_source(fe,
+                                          (priv->role == TDA18271_SLAVE) ?
+                                          TDA18271_CAL_PLL :
+                                          TDA18271_MAIN_PLL, force);
+}
+
+static inline void tda18271_set_if_notch(struct dvb_frontend *fe)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+
+       switch (priv->mode) {
+       case TDA18271_ANALOG:
+               regs[R_MPD]  &= ~0x80; /* IF notch = 0 */
+               break;
+       case TDA18271_DIGITAL:
+               regs[R_MPD]  |= 0x80; /* IF notch = 1 */
+               break;
+       }
+}
+
+static int tda18271_channel_configuration(struct dvb_frontend *fe,
+                                         struct tda18271_std_map_item *map,
+                                         u32 freq, u32 bw)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       int ret;
+       u32 N;
+
+       /* update TV broadcast parameters */
+
+       /* set standard */
+       regs[R_EP3]  &= ~0x1f; /* clear std bits */
+       regs[R_EP3]  |= (map->agc_mode << 3) | map->std;
+
+       if (priv->id == TDA18271HDC2) {
+               /* set rfagc to high speed mode */
+               regs[R_EP3] &= ~0x04;
+       }
+
+       /* set cal mode to normal */
+       regs[R_EP4]  &= ~0x03;
+
+       /* update IF output level */
+       regs[R_EP4]  &= ~0x1c; /* clear if level bits */
+       regs[R_EP4]  |= (map->if_lvl << 2);
+
+       /* update FM_RFn */
+       regs[R_EP4]  &= ~0x80;
+       regs[R_EP4]  |= map->fm_rfn << 7;
+
+       /* update rf top / if top */
+       regs[R_EB22]  = 0x00;
+       regs[R_EB22] |= map->rfagc_top;
+       ret = tda18271_write_regs(fe, R_EB22, 1);
+       if (tda_fail(ret))
+               goto fail;
+
+       /* --------------------------------------------------------------- */
+
+       /* disable Power Level Indicator */
+       regs[R_EP1]  |= 0x40;
+
+       /* make sure thermometer is off */
+       regs[R_TM]   &= ~0x10;
+
+       /* frequency dependent parameters */
+
+       tda18271_calc_ir_measure(fe, &freq);
+
+       tda18271_calc_bp_filter(fe, &freq);
+
+       tda18271_calc_rf_band(fe, &freq);
+
+       tda18271_calc_gain_taper(fe, &freq);
+
+       /* --------------------------------------------------------------- */
+
+       /* dual tuner and agc1 extra configuration */
+
+       switch (priv->role) {
+       case TDA18271_MASTER:
+               regs[R_EB1]  |= 0x04; /* main vco */
+               break;
+       case TDA18271_SLAVE:
+               regs[R_EB1]  &= ~0x04; /* cal vco */
+               break;
+       }
+
+       /* agc1 always active */
+       regs[R_EB1]  &= ~0x02;
+
+       /* agc1 has priority on agc2 */
+       regs[R_EB1]  &= ~0x01;
+
+       ret = tda18271_write_regs(fe, R_EB1, 1);
+       if (tda_fail(ret))
+               goto fail;
+
+       /* --------------------------------------------------------------- */
+
+       N = map->if_freq * 1000 + freq;
+
+       switch (priv->role) {
+       case TDA18271_MASTER:
+               tda18271_calc_main_pll(fe, N);
+               tda18271_set_if_notch(fe);
+               tda18271_write_regs(fe, R_MPD, 4);
+               break;
+       case TDA18271_SLAVE:
+               tda18271_calc_cal_pll(fe, N);
+               tda18271_write_regs(fe, R_CPD, 4);
+
+               regs[R_MPD] = regs[R_CPD] & 0x7f;
+               tda18271_set_if_notch(fe);
+               tda18271_write_regs(fe, R_MPD, 1);
+               break;
+       }
+
+       ret = tda18271_write_regs(fe, R_TM, 7);
+       if (tda_fail(ret))
+               goto fail;
+
+       /* force charge pump source */
+       charge_pump_source(fe, 1);
+
+       msleep(1);
+
+       /* return pll to normal operation */
+       charge_pump_source(fe, 0);
+
+       msleep(20);
+
+       if (priv->id == TDA18271HDC2) {
+               /* set rfagc to normal speed mode */
+               if (map->fm_rfn)
+                       regs[R_EP3] &= ~0x04;
+               else
+                       regs[R_EP3] |= 0x04;
+               ret = tda18271_write_regs(fe, R_EP3, 1);
+       }
+fail:
+       return ret;
+}
+
+static int tda18271_read_thermometer(struct dvb_frontend *fe)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       int tm;
+
+       /* switch thermometer on */
+       regs[R_TM]   |= 0x10;
+       tda18271_write_regs(fe, R_TM, 1);
+
+       /* read thermometer info */
+       tda18271_read_regs(fe);
+
+       if ((((regs[R_TM] & 0x0f) == 0x00) && ((regs[R_TM] & 0x20) == 0x20)) ||
+           (((regs[R_TM] & 0x0f) == 0x08) && ((regs[R_TM] & 0x20) == 0x00))) {
+
+               if ((regs[R_TM] & 0x20) == 0x20)
+                       regs[R_TM] &= ~0x20;
+               else
+                       regs[R_TM] |= 0x20;
+
+               tda18271_write_regs(fe, R_TM, 1);
+
+               msleep(10); /* temperature sensing */
+
+               /* read thermometer info */
+               tda18271_read_regs(fe);
+       }
+
+       tm = tda18271_lookup_thermometer(fe);
+
+       /* switch thermometer off */
+       regs[R_TM]   &= ~0x10;
+       tda18271_write_regs(fe, R_TM, 1);
+
+       /* set CAL mode to normal */
+       regs[R_EP4]  &= ~0x03;
+       tda18271_write_regs(fe, R_EP4, 1);
+
+       return tm;
+}
+
+/* ------------------------------------------------------------------ */
+
+static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
+                                                    u32 freq)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
+       unsigned char *regs = priv->tda18271_regs;
+       int i, ret;
+       u8 tm_current, dc_over_dt, rf_tab;
+       s32 rfcal_comp, approx;
+
+       /* power up */
+       ret = tda18271_set_standby_mode(fe, 0, 0, 0);
+       if (tda_fail(ret))
+               goto fail;
+
+       /* read die current temperature */
+       tm_current = tda18271_read_thermometer(fe);
+
+       /* frequency dependent parameters */
+
+       tda18271_calc_rf_cal(fe, &freq);
+       rf_tab = regs[R_EB14];
+
+       i = tda18271_lookup_rf_band(fe, &freq, NULL);
+       if (tda_fail(i))
+               return i;
+
+       if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) {
+               approx = map[i].rf_a1 * (s32)(freq / 1000 - map[i].rf1) +
+                       map[i].rf_b1 + rf_tab;
+       } else {
+               approx = map[i].rf_a2 * (s32)(freq / 1000 - map[i].rf2) +
+                       map[i].rf_b2 + rf_tab;
+       }
+
+       if (approx < 0)
+               approx = 0;
+       if (approx > 255)
+               approx = 255;
+
+       tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt);
+
+       /* calculate temperature compensation */
+       rfcal_comp = dc_over_dt * (s32)(tm_current - priv->tm_rfcal) / 1000;
+
+       regs[R_EB14] = (unsigned char)(approx + rfcal_comp);
+       ret = tda18271_write_regs(fe, R_EB14, 1);
+fail:
+       return ret;
+}
+
+static int tda18271_por(struct dvb_frontend *fe)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       int ret;
+
+       /* power up detector 1 */
+       regs[R_EB12] &= ~0x20;
+       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] &= ~0x03; /* set agc1_gain to  6 dB */
+       ret = tda18271_write_regs(fe, R_EB18, 1);
+       if (tda_fail(ret))
+               goto fail;
+
+       regs[R_EB21] |= 0x03; /* set agc2_gain to -6 dB */
+
+       /* POR mode */
+       ret = tda18271_set_standby_mode(fe, 1, 0, 0);
+       if (tda_fail(ret))
+               goto fail;
+
+       /* disable 1.5 MHz low pass filter */
+       regs[R_EB23] &= ~0x04; /* forcelp_fc2_en = 0 */
+       regs[R_EB23] &= ~0x02; /* XXX: lp_fc[2] = 0 */
+       ret = tda18271_write_regs(fe, R_EB21, 3);
+fail:
+       return ret;
+}
+
+static int tda18271_calibrate_rf(struct dvb_frontend *fe, u32 freq)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       u32 N;
+
+       /* set CAL mode to normal */
+       regs[R_EP4]  &= ~0x03;
+       tda18271_write_regs(fe, R_EP4, 1);
+
+       /* switch off agc1 */
+       regs[R_EP3]  |= 0x40; /* sm_lt = 1 */
+
+       regs[R_EB18] |= 0x03; /* set agc1_gain to 15 dB */
+       tda18271_write_regs(fe, R_EB18, 1);
+
+       /* frequency dependent parameters */
+
+       tda18271_calc_bp_filter(fe, &freq);
+       tda18271_calc_gain_taper(fe, &freq);
+       tda18271_calc_rf_band(fe, &freq);
+       tda18271_calc_km(fe, &freq);
+
+       tda18271_write_regs(fe, R_EP1, 3);
+       tda18271_write_regs(fe, R_EB13, 1);
+
+       /* main pll charge pump source */
+       tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 1);
+
+       /* cal pll charge pump source */
+       tda18271_charge_pump_source(fe, TDA18271_CAL_PLL, 1);
+
+       /* force dcdc converter to 0 V */
+       regs[R_EB14] = 0x00;
+       tda18271_write_regs(fe, R_EB14, 1);
+
+       /* disable plls lock */
+       regs[R_EB20] &= ~0x20;
+       tda18271_write_regs(fe, R_EB20, 1);
+
+       /* set CAL mode to RF tracking filter calibration */
+       regs[R_EP4]  |= 0x03;
+       tda18271_write_regs(fe, R_EP4, 2);
+
+       /* --------------------------------------------------------------- */
+
+       /* set the internal calibration signal */
+       N = freq;
+
+       tda18271_calc_cal_pll(fe, N);
+       tda18271_write_regs(fe, R_CPD, 4);
+
+       /* downconvert internal calibration */
+       N += 1000000;
+
+       tda18271_calc_main_pll(fe, N);
+       tda18271_write_regs(fe, R_MPD, 4);
+
+       msleep(5);
+
+       tda18271_write_regs(fe, R_EP2, 1);
+       tda18271_write_regs(fe, R_EP1, 1);
+       tda18271_write_regs(fe, R_EP2, 1);
+       tda18271_write_regs(fe, R_EP1, 1);
+
+       /* --------------------------------------------------------------- */
+
+       /* normal operation for the main pll */
+       tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 0);
+
+       /* normal operation for the cal pll  */
+       tda18271_charge_pump_source(fe, TDA18271_CAL_PLL, 0);
+
+       msleep(10); /* plls locking */
+
+       /* launch the rf tracking filters calibration */
+       regs[R_EB20]  |= 0x20;
+       tda18271_write_regs(fe, R_EB20, 1);
+
+       msleep(60); /* calibration */
+
+       /* --------------------------------------------------------------- */
+
+       /* set CAL mode to normal */
+       regs[R_EP4]  &= ~0x03;
+
+       /* switch on agc1 */
+       regs[R_EP3]  &= ~0x40; /* sm_lt = 0 */
+
+       regs[R_EB18] &= ~0x03; /* set agc1_gain to  6 dB */
+       tda18271_write_regs(fe, R_EB18, 1);
+
+       tda18271_write_regs(fe, R_EP3, 2);
+
+       /* synchronization */
+       tda18271_write_regs(fe, R_EP1, 1);
+
+       /* get calibration result */
+       tda18271_read_extended(fe);
+
+       return regs[R_EB14];
+}
+
+static int tda18271_powerscan(struct dvb_frontend *fe,
+                             u32 *freq_in, u32 *freq_out)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       int sgn, bcal, count, wait, ret;
+       u8 cid_target;
+       u16 count_limit;
+       u32 freq;
+
+       freq = *freq_in;
+
+       tda18271_calc_rf_band(fe, &freq);
+       tda18271_calc_rf_cal(fe, &freq);
+       tda18271_calc_gain_taper(fe, &freq);
+       tda18271_lookup_cid_target(fe, &freq, &cid_target, &count_limit);
+
+       tda18271_write_regs(fe, R_EP2, 1);
+       tda18271_write_regs(fe, R_EB14, 1);
+
+       /* downconvert frequency */
+       freq += 1000000;
+
+       tda18271_calc_main_pll(fe, freq);
+       tda18271_write_regs(fe, R_MPD, 4);
+
+       msleep(5); /* pll locking */
+
+       /* detection mode */
+       regs[R_EP4]  &= ~0x03;
+       regs[R_EP4]  |= 0x01;
+       tda18271_write_regs(fe, R_EP4, 1);
+
+       /* launch power detection measurement */
+       tda18271_write_regs(fe, R_EP2, 1);
+
+       /* read power detection info, stored in EB10 */
+       ret = tda18271_read_extended(fe);
+       if (tda_fail(ret))
+               return ret;
+
+       /* algorithm initialization */
+       sgn = 1;
+       *freq_out = *freq_in;
+       bcal = 0;
+       count = 0;
+       wait = false;
+
+       while ((regs[R_EB10] & 0x3f) < cid_target) {
+               /* downconvert updated freq to 1 MHz */
+               freq = *freq_in + (sgn * count) + 1000000;
+
+               tda18271_calc_main_pll(fe, freq);
+               tda18271_write_regs(fe, R_MPD, 4);
+
+               if (wait) {
+                       msleep(5); /* pll locking */
+                       wait = false;
+               } else
+                       udelay(100); /* pll locking */
+
+               /* launch power detection measurement */
+               tda18271_write_regs(fe, R_EP2, 1);
+
+               /* read power detection info, stored in EB10 */
+               ret = tda18271_read_extended(fe);
+               if (tda_fail(ret))
+                       return ret;
+
+               count += 200;
+
+               if (count <= count_limit)
+                       continue;
+
+               if (sgn <= 0)
+                       break;
+
+               sgn = -1 * sgn;
+               count = 200;
+               wait = true;
+       }
+
+       if ((regs[R_EB10] & 0x3f) >= cid_target) {
+               bcal = 1;
+               *freq_out = freq - 1000000;
+       } else
+               bcal = 0;
+
+       tda_cal("bcal = %d, freq_in = %d, freq_out = %d (freq = %d)\n",
+               bcal, *freq_in, *freq_out, freq);
+
+       return bcal;
+}
+
+static int tda18271_powerscan_init(struct dvb_frontend *fe)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       int ret;
+
+       /* set standard to digital */
+       regs[R_EP3]  &= ~0x1f; /* clear std bits */
+       regs[R_EP3]  |= 0x12;
+
+       /* set cal mode to normal */
+       regs[R_EP4]  &= ~0x03;
+
+       /* update IF output level */
+       regs[R_EP4]  &= ~0x1c; /* clear if level bits */
+
+       ret = tda18271_write_regs(fe, R_EP3, 2);
+       if (tda_fail(ret))
+               goto fail;
+
+       regs[R_EB18] &= ~0x03; /* set agc1_gain to   6 dB */
+       ret = tda18271_write_regs(fe, R_EB18, 1);
+       if (tda_fail(ret))
+               goto fail;
+
+       regs[R_EB21] &= ~0x03; /* set agc2_gain to -15 dB */
+
+       /* 1.5 MHz low pass filter */
+       regs[R_EB23] |= 0x04; /* forcelp_fc2_en = 1 */
+       regs[R_EB23] |= 0x02; /* lp_fc[2] = 1 */
+
+       ret = tda18271_write_regs(fe, R_EB21, 3);
+fail:
+       return ret;
+}
+
+static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
+       unsigned char *regs = priv->tda18271_regs;
+       int bcal, rf, i;
+       s32 divisor, dividend;
+#define RF1 0
+#define RF2 1
+#define RF3 2
+       u32 rf_default[3];
+       u32 rf_freq[3];
+       s32 prog_cal[3];
+       s32 prog_tab[3];
+
+       i = tda18271_lookup_rf_band(fe, &freq, NULL);
+
+       if (tda_fail(i))
+               return i;
+
+       rf_default[RF1] = 1000 * map[i].rf1_def;
+       rf_default[RF2] = 1000 * map[i].rf2_def;
+       rf_default[RF3] = 1000 * map[i].rf3_def;
+
+       for (rf = RF1; rf <= RF3; rf++) {
+               if (0 == rf_default[rf])
+                       return 0;
+               tda_cal("freq = %d, rf = %d\n", freq, rf);
+
+               /* look for optimized calibration frequency */
+               bcal = tda18271_powerscan(fe, &rf_default[rf], &rf_freq[rf]);
+               if (tda_fail(bcal))
+                       return bcal;
+
+               tda18271_calc_rf_cal(fe, &rf_freq[rf]);
+               prog_tab[rf] = (s32)regs[R_EB14];
+
+               if (1 == bcal)
+                       prog_cal[rf] =
+                               (s32)tda18271_calibrate_rf(fe, rf_freq[rf]);
+               else
+                       prog_cal[rf] = prog_tab[rf];
+
+               switch (rf) {
+               case RF1:
+                       map[i].rf_a1 = 0;
+                       map[i].rf_b1 = (prog_cal[RF1] - prog_tab[RF1]);
+                       map[i].rf1   = rf_freq[RF1] / 1000;
+                       break;
+               case RF2:
+                       dividend = (prog_cal[RF2] - prog_tab[RF2] -
+                                   prog_cal[RF1] + prog_tab[RF1]);
+                       divisor = (s32)(rf_freq[RF2] - rf_freq[RF1]) / 1000;
+                       map[i].rf_a1 = (dividend / divisor);
+                       map[i].rf2   = rf_freq[RF2] / 1000;
+                       break;
+               case RF3:
+                       dividend = (prog_cal[RF3] - prog_tab[RF3] -
+                                   prog_cal[RF2] + prog_tab[RF2]);
+                       divisor = (s32)(rf_freq[RF3] - rf_freq[RF2]) / 1000;
+                       map[i].rf_a2 = (dividend / divisor);
+                       map[i].rf_b2 = (prog_cal[RF2] - prog_tab[RF2]);
+                       map[i].rf3   = rf_freq[RF3] / 1000;
+                       break;
+               default:
+                       BUG();
+               }
+       }
+
+       return 0;
+}
+
+static int tda18271_calc_rf_filter_curve(struct dvb_frontend *fe)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned int i;
+       int ret;
+
+       tda_info("tda18271: performing RF tracking filter calibration\n");
+
+       /* wait for die temperature stabilization */
+       msleep(200);
+
+       ret = tda18271_powerscan_init(fe);
+       if (tda_fail(ret))
+               goto fail;
+
+       /* rf band calibration */
+       for (i = 0; priv->rf_cal_state[i].rfmax != 0; i++) {
+               ret =
+               tda18271_rf_tracking_filters_init(fe, 1000 *
+                                                 priv->rf_cal_state[i].rfmax);
+               if (tda_fail(ret))
+                       goto fail;
+       }
+
+       priv->tm_rfcal = tda18271_read_thermometer(fe);
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------ */
+
+static int tda18271c2_rf_cal_init(struct dvb_frontend *fe)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       int ret;
+
+       /* test RF_CAL_OK to see if we need init */
+       if ((regs[R_EP1] & 0x10) == 0)
+               priv->cal_initialized = false;
+
+       if (priv->cal_initialized)
+               return 0;
+
+       ret = tda18271_calc_rf_filter_curve(fe);
+       if (tda_fail(ret))
+               goto fail;
+
+       ret = tda18271_por(fe);
+       if (tda_fail(ret))
+               goto fail;
+
+       tda_info("tda18271: RF tracking filter calibration complete\n");
+
+       priv->cal_initialized = true;
+       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,
+                                                    u32 freq, u32 bw)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       int ret;
+       u32 N = 0;
+
+       /* calculate bp filter */
+       tda18271_calc_bp_filter(fe, &freq);
+       tda18271_write_regs(fe, R_EP1, 1);
+
+       regs[R_EB4]  &= 0x07;
+       regs[R_EB4]  |= 0x60;
+       tda18271_write_regs(fe, R_EB4, 1);
+
+       regs[R_EB7]   = 0x60;
+       tda18271_write_regs(fe, R_EB7, 1);
+
+       regs[R_EB14]  = 0x00;
+       tda18271_write_regs(fe, R_EB14, 1);
+
+       regs[R_EB20]  = 0xcc;
+       tda18271_write_regs(fe, R_EB20, 1);
+
+       /* set cal mode to RF tracking filter calibration */
+       regs[R_EP4]  |= 0x03;
+
+       /* calculate cal pll */
+
+       switch (priv->mode) {
+       case TDA18271_ANALOG:
+               N = freq - 1250000;
+               break;
+       case TDA18271_DIGITAL:
+               N = freq + bw / 2;
+               break;
+       }
+
+       tda18271_calc_cal_pll(fe, N);
+
+       /* calculate main pll */
+
+       switch (priv->mode) {
+       case TDA18271_ANALOG:
+               N = freq - 250000;
+               break;
+       case TDA18271_DIGITAL:
+               N = freq + bw / 2 + 1000000;
+               break;
+       }
+
+       tda18271_calc_main_pll(fe, N);
+
+       ret = tda18271_write_regs(fe, R_EP3, 11);
+       if (tda_fail(ret))
+               return ret;
+
+       msleep(5); /* RF tracking filter calibration initialization */
+
+       /* search for K,M,CO for RF calibration */
+       tda18271_calc_km(fe, &freq);
+       tda18271_write_regs(fe, R_EB13, 1);
+
+       /* search for rf band */
+       tda18271_calc_rf_band(fe, &freq);
+
+       /* search for gain taper */
+       tda18271_calc_gain_taper(fe, &freq);
+
+       tda18271_write_regs(fe, R_EP2, 1);
+       tda18271_write_regs(fe, R_EP1, 1);
+       tda18271_write_regs(fe, R_EP2, 1);
+       tda18271_write_regs(fe, R_EP1, 1);
+
+       regs[R_EB4]  &= 0x07;
+       regs[R_EB4]  |= 0x40;
+       tda18271_write_regs(fe, R_EB4, 1);
+
+       regs[R_EB7]   = 0x40;
+       tda18271_write_regs(fe, R_EB7, 1);
+       msleep(10); /* pll locking */
+
+       regs[R_EB20]  = 0xec;
+       tda18271_write_regs(fe, R_EB20, 1);
+       msleep(60); /* RF tracking filter calibration completion */
+
+       regs[R_EP4]  &= ~0x03; /* set cal mode to normal */
+       tda18271_write_regs(fe, R_EP4, 1);
+
+       tda18271_write_regs(fe, R_EP1, 1);
+
+       /* RF tracking filter correction for VHF_Low band */
+       if (0 == tda18271_calc_rf_cal(fe, &freq))
+               tda18271_write_regs(fe, R_EB14, 1);
+
+       return 0;
+}
+
+/* ------------------------------------------------------------------ */
+
+static int tda18271_ir_cal_init(struct dvb_frontend *fe)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       int ret;
+
+       ret = tda18271_read_regs(fe);
+       if (tda_fail(ret))
+               goto fail;
+
+       /* test IR_CAL_OK to see if we need init */
+       if ((regs[R_EP1] & 0x08) == 0)
+               ret = tda18271_init_regs(fe);
+fail:
+       return ret;
+}
+
+static int tda18271_init(struct dvb_frontend *fe)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       int ret;
+
+       mutex_lock(&priv->lock);
+
+       /* full power up */
+       ret = tda18271_set_standby_mode(fe, 0, 0, 0);
+       if (tda_fail(ret))
+               goto fail;
+
+       /* initialization */
+       ret = tda18271_ir_cal_init(fe);
+       if (tda_fail(ret))
+               goto fail;
+
+       if (priv->id == TDA18271HDC2)
+               tda18271c2_rf_cal_init(fe);
+fail:
+       mutex_unlock(&priv->lock);
+
+       return ret;
+}
+
+static int tda18271_sleep(struct dvb_frontend *fe)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       int ret;
+
+       mutex_lock(&priv->lock);
+
+       /* enter standby mode, with required output features enabled */
+       ret = tda18271_toggle_output(fe, 1);
+
+       mutex_unlock(&priv->lock);
+
+       return ret;
+}
+
+/* ------------------------------------------------------------------ */
+
+static int tda18271_agc(struct dvb_frontend *fe)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       int ret = 0;
+
+       switch (priv->config) {
+       case 0:
+               /* no external agc configuration required */
+               if (tda18271_debug & DBG_ADV)
+                       tda_dbg("no agc configuration provided\n");
+               break;
+       case 3:
+               /* switch with GPIO of saa713x */
+               tda_dbg("invoking callback\n");
+               if (fe->callback)
+                       ret = fe->callback(priv->i2c_props.adap->algo_data,
+                                          DVB_FRONTEND_COMPONENT_TUNER,
+                                          TDA18271_CALLBACK_CMD_AGC_ENABLE,
+                                          priv->mode);
+               break;
+       case 1:
+       case 2:
+       default:
+               /* n/a - currently not supported */
+               tda_err("unsupported configuration: %d\n", priv->config);
+               ret = -EINVAL;
+               break;
+       }
+       return ret;
+}
+
+static int tda18271_tune(struct dvb_frontend *fe,
+                        struct tda18271_std_map_item *map, u32 freq, u32 bw)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       int ret;
+
+       tda_dbg("freq = %d, ifc = %d, bw = %d, agc_mode = %d, std = %d\n",
+               freq, map->if_freq, bw, map->agc_mode, map->std);
+
+       ret = tda18271_agc(fe);
+       if (tda_fail(ret))
+               tda_warn("failed to configure agc\n");
+
+       ret = tda18271_init(fe);
+       if (tda_fail(ret))
+               goto fail;
+
+       mutex_lock(&priv->lock);
+
+       switch (priv->id) {
+       case TDA18271HDC1:
+               tda18271c1_rf_tracking_filter_calibration(fe, freq, bw);
+               break;
+       case TDA18271HDC2:
+               tda18271c2_rf_tracking_filters_correction(fe, freq);
+               break;
+       }
+       ret = tda18271_channel_configuration(fe, map, freq, bw);
+
+       mutex_unlock(&priv->lock);
+fail:
+       return ret;
+}
+
+/* ------------------------------------------------------------------ */
+
+static int tda18271_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u32 delsys = c->delivery_system;
+       u32 bw = c->bandwidth_hz;
+       u32 freq = c->frequency;
+       struct tda18271_priv *priv = fe->tuner_priv;
+       struct tda18271_std_map *std_map = &priv->std;
+       struct tda18271_std_map_item *map;
+       int ret;
+
+       priv->mode = TDA18271_DIGITAL;
+
+       switch (delsys) {
+       case SYS_ATSC:
+               map = &std_map->atsc_6;
+               bw = 6000000;
+               break;
+       case SYS_ISDBT:
+       case SYS_DVBT:
+       case SYS_DVBT2:
+               if (bw <= 6000000) {
+                       map = &std_map->dvbt_6;
+               } else if (bw <= 7000000) {
+                       map = &std_map->dvbt_7;
+               } else {
+                       map = &std_map->dvbt_8;
+               }
+               break;
+       case SYS_DVBC_ANNEX_B:
+               bw = 6000000;
+               /* falltrough */
+       case SYS_DVBC_ANNEX_A:
+       case SYS_DVBC_ANNEX_C:
+               if (bw <= 6000000) {
+                       map = &std_map->qam_6;
+               } else if (bw <= 7000000) {
+                       map = &std_map->qam_7;
+               } else {
+                       map = &std_map->qam_8;
+               }
+               break;
+       default:
+               tda_warn("modulation type not supported!\n");
+               return -EINVAL;
+       }
+
+       /* When tuning digital, the analog demod must be tri-stated */
+       if (fe->ops.analog_ops.standby)
+               fe->ops.analog_ops.standby(fe);
+
+       ret = tda18271_tune(fe, map, freq, bw);
+
+       if (tda_fail(ret))
+               goto fail;
+
+       priv->if_freq   = map->if_freq;
+       priv->frequency = freq;
+       priv->bandwidth = bw;
+fail:
+       return ret;
+}
+
+static int tda18271_set_analog_params(struct dvb_frontend *fe,
+                                     struct analog_parameters *params)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       struct tda18271_std_map *std_map = &priv->std;
+       struct tda18271_std_map_item *map;
+       char *mode;
+       int ret;
+       u32 freq = params->frequency * 125 *
+               ((params->mode == V4L2_TUNER_RADIO) ? 1 : 1000) / 2;
+
+       priv->mode = TDA18271_ANALOG;
+
+       if (params->mode == V4L2_TUNER_RADIO) {
+               map = &std_map->fm_radio;
+               mode = "fm";
+       } else if (params->std & V4L2_STD_MN) {
+               map = &std_map->atv_mn;
+               mode = "MN";
+       } else if (params->std & V4L2_STD_B) {
+               map = &std_map->atv_b;
+               mode = "B";
+       } else if (params->std & V4L2_STD_GH) {
+               map = &std_map->atv_gh;
+               mode = "GH";
+       } else if (params->std & V4L2_STD_PAL_I) {
+               map = &std_map->atv_i;
+               mode = "I";
+       } else if (params->std & V4L2_STD_DK) {
+               map = &std_map->atv_dk;
+               mode = "DK";
+       } else if (params->std & V4L2_STD_SECAM_L) {
+               map = &std_map->atv_l;
+               mode = "L";
+       } else if (params->std & V4L2_STD_SECAM_LC) {
+               map = &std_map->atv_lc;
+               mode = "L'";
+       } else {
+               map = &std_map->atv_i;
+               mode = "xx";
+       }
+
+       tda_dbg("setting tda18271 to system %s\n", mode);
+
+       ret = tda18271_tune(fe, map, freq, 0);
+
+       if (tda_fail(ret))
+               goto fail;
+
+       priv->if_freq   = map->if_freq;
+       priv->frequency = freq;
+       priv->bandwidth = 0;
+fail:
+       return ret;
+}
+
+static int tda18271_release(struct dvb_frontend *fe)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+
+       mutex_lock(&tda18271_list_mutex);
+
+       if (priv)
+               hybrid_tuner_release_state(priv);
+
+       mutex_unlock(&tda18271_list_mutex);
+
+       fe->tuner_priv = NULL;
+
+       return 0;
+}
+
+static int tda18271_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static int tda18271_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       *bandwidth = priv->bandwidth;
+       return 0;
+}
+
+static int tda18271_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       *frequency = (u32)priv->if_freq * 1000;
+       return 0;
+}
+
+/* ------------------------------------------------------------------ */
+
+#define tda18271_update_std(std_cfg, name) do {                                \
+       if (map->std_cfg.if_freq +                                      \
+               map->std_cfg.agc_mode + map->std_cfg.std +              \
+               map->std_cfg.if_lvl + map->std_cfg.rfagc_top > 0) {     \
+               tda_dbg("Using custom std config for %s\n", name);      \
+               memcpy(&std->std_cfg, &map->std_cfg,                    \
+                       sizeof(struct tda18271_std_map_item));          \
+       } } while (0)
+
+#define tda18271_dump_std_item(std_cfg, name) do {                     \
+       tda_dbg("(%s) if_freq = %d, agc_mode = %d, std = %d, "          \
+               "if_lvl = %d, rfagc_top = 0x%02x\n",                    \
+               name, std->std_cfg.if_freq,                             \
+               std->std_cfg.agc_mode, std->std_cfg.std,                \
+               std->std_cfg.if_lvl, std->std_cfg.rfagc_top);           \
+       } while (0)
+
+static int tda18271_dump_std_map(struct dvb_frontend *fe)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       struct tda18271_std_map *std = &priv->std;
+
+       tda_dbg("========== STANDARD MAP SETTINGS ==========\n");
+       tda18271_dump_std_item(fm_radio, "  fm  ");
+       tda18271_dump_std_item(atv_b,  "atv b ");
+       tda18271_dump_std_item(atv_dk, "atv dk");
+       tda18271_dump_std_item(atv_gh, "atv gh");
+       tda18271_dump_std_item(atv_i,  "atv i ");
+       tda18271_dump_std_item(atv_l,  "atv l ");
+       tda18271_dump_std_item(atv_lc, "atv l'");
+       tda18271_dump_std_item(atv_mn, "atv mn");
+       tda18271_dump_std_item(atsc_6, "atsc 6");
+       tda18271_dump_std_item(dvbt_6, "dvbt 6");
+       tda18271_dump_std_item(dvbt_7, "dvbt 7");
+       tda18271_dump_std_item(dvbt_8, "dvbt 8");
+       tda18271_dump_std_item(qam_6,  "qam 6 ");
+       tda18271_dump_std_item(qam_8,  "qam 8 ");
+
+       return 0;
+}
+
+static int tda18271_update_std_map(struct dvb_frontend *fe,
+                                  struct tda18271_std_map *map)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       struct tda18271_std_map *std = &priv->std;
+
+       if (!map)
+               return -EINVAL;
+
+       tda18271_update_std(fm_radio, "fm");
+       tda18271_update_std(atv_b,  "atv b");
+       tda18271_update_std(atv_dk, "atv dk");
+       tda18271_update_std(atv_gh, "atv gh");
+       tda18271_update_std(atv_i,  "atv i");
+       tda18271_update_std(atv_l,  "atv l");
+       tda18271_update_std(atv_lc, "atv l'");
+       tda18271_update_std(atv_mn, "atv mn");
+       tda18271_update_std(atsc_6, "atsc 6");
+       tda18271_update_std(dvbt_6, "dvbt 6");
+       tda18271_update_std(dvbt_7, "dvbt 7");
+       tda18271_update_std(dvbt_8, "dvbt 8");
+       tda18271_update_std(qam_6,  "qam 6");
+       tda18271_update_std(qam_8,  "qam 8");
+
+       return 0;
+}
+
+static int tda18271_get_id(struct dvb_frontend *fe)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       char *name;
+
+       mutex_lock(&priv->lock);
+       tda18271_read_regs(fe);
+       mutex_unlock(&priv->lock);
+
+       switch (regs[R_ID] & 0x7f) {
+       case 3:
+               name = "TDA18271HD/C1";
+               priv->id = TDA18271HDC1;
+               break;
+       case 4:
+               name = "TDA18271HD/C2";
+               priv->id = TDA18271HDC2;
+               break;
+       default:
+               tda_info("Unknown device (%i) detected @ %d-%04x, device not supported.\n",
+                        regs[R_ID], i2c_adapter_id(priv->i2c_props.adap),
+                        priv->i2c_props.addr);
+               return -EINVAL;
+       }
+
+       tda_info("%s detected @ %d-%04x\n", name,
+                i2c_adapter_id(priv->i2c_props.adap), priv->i2c_props.addr);
+
+       return 0;
+}
+
+static int tda18271_setup_configuration(struct dvb_frontend *fe,
+                                       struct tda18271_config *cfg)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+
+       priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
+       priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
+       priv->config = (cfg) ? cfg->config : 0;
+       priv->small_i2c = (cfg) ?
+               cfg->small_i2c : TDA18271_39_BYTE_CHUNK_INIT;
+       priv->output_opt = (cfg) ?
+               cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON;
+
+       return 0;
+}
+
+static inline int tda18271_need_cal_on_startup(struct tda18271_config *cfg)
+{
+       /* tda18271_cal_on_startup == -1 when cal module option is unset */
+       return ((tda18271_cal_on_startup == -1) ?
+               /* honor configuration setting */
+               ((cfg) && (cfg->rf_cal_on_startup)) :
+               /* module option overrides configuration setting */
+               (tda18271_cal_on_startup)) ? 1 : 0;
+}
+
+static int tda18271_set_config(struct dvb_frontend *fe, void *priv_cfg)
+{
+       struct tda18271_config *cfg = (struct tda18271_config *) priv_cfg;
+
+       tda18271_setup_configuration(fe, cfg);
+
+       if (tda18271_need_cal_on_startup(cfg))
+               tda18271_init(fe);
+
+       /* override default std map with values in config struct */
+       if ((cfg) && (cfg->std_map))
+               tda18271_update_std_map(fe, cfg->std_map);
+
+       return 0;
+}
+
+static const struct dvb_tuner_ops tda18271_tuner_ops = {
+       .info = {
+               .name = "NXP TDA18271HD",
+               .frequency_min  =  45000000,
+               .frequency_max  = 864000000,
+               .frequency_step =     62500
+       },
+       .init              = tda18271_init,
+       .sleep             = tda18271_sleep,
+       .set_params        = tda18271_set_params,
+       .set_analog_params = tda18271_set_analog_params,
+       .release           = tda18271_release,
+       .set_config        = tda18271_set_config,
+       .get_frequency     = tda18271_get_frequency,
+       .get_bandwidth     = tda18271_get_bandwidth,
+       .get_if_frequency  = tda18271_get_if_frequency,
+};
+
+struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
+                                    struct i2c_adapter *i2c,
+                                    struct tda18271_config *cfg)
+{
+       struct tda18271_priv *priv = NULL;
+       int instance, ret;
+
+       mutex_lock(&tda18271_list_mutex);
+
+       instance = hybrid_tuner_request_state(struct tda18271_priv, priv,
+                                             hybrid_tuner_instance_list,
+                                             i2c, addr, "tda18271");
+       switch (instance) {
+       case 0:
+               goto fail;
+       case 1:
+               /* new tuner instance */
+               fe->tuner_priv = priv;
+
+               tda18271_setup_configuration(fe, cfg);
+
+               priv->cal_initialized = false;
+               mutex_init(&priv->lock);
+
+               ret = tda18271_get_id(fe);
+               if (tda_fail(ret))
+                       goto fail;
+
+               ret = tda18271_assign_map_layout(fe);
+               if (tda_fail(ret))
+                       goto fail;
+
+               mutex_lock(&priv->lock);
+               tda18271_init_regs(fe);
+
+               if ((tda18271_need_cal_on_startup(cfg)) &&
+                   (priv->id == TDA18271HDC2))
+                       tda18271c2_rf_cal_init(fe);
+
+               mutex_unlock(&priv->lock);
+               break;
+       default:
+               /* existing tuner instance */
+               fe->tuner_priv = priv;
+
+               /* allow dvb driver to override configuration settings */
+               if (cfg) {
+                       if (cfg->gate != TDA18271_GATE_ANALOG)
+                               priv->gate = cfg->gate;
+                       if (cfg->role)
+                               priv->role = cfg->role;
+                       if (cfg->config)
+                               priv->config = cfg->config;
+                       if (cfg->small_i2c)
+                               priv->small_i2c = cfg->small_i2c;
+                       if (cfg->output_opt)
+                               priv->output_opt = cfg->output_opt;
+                       if (cfg->std_map)
+                               tda18271_update_std_map(fe, cfg->std_map);
+               }
+               if (tda18271_need_cal_on_startup(cfg))
+                       tda18271_init(fe);
+               break;
+       }
+
+       /* override default std map with values in config struct */
+       if ((cfg) && (cfg->std_map))
+               tda18271_update_std_map(fe, cfg->std_map);
+
+       mutex_unlock(&tda18271_list_mutex);
+
+       memcpy(&fe->ops.tuner_ops, &tda18271_tuner_ops,
+              sizeof(struct dvb_tuner_ops));
+
+       if (tda18271_debug & (DBG_MAP | DBG_ADV))
+               tda18271_dump_std_map(fe);
+
+       return fe;
+fail:
+       mutex_unlock(&tda18271_list_mutex);
+
+       tda18271_release(fe);
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(tda18271_attach);
+MODULE_DESCRIPTION("NXP TDA18271HD analog / digital tuner driver");
+MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.4");
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/tuners/tda18271-maps.c b/drivers/media/tuners/tda18271-maps.c
new file mode 100644 (file)
index 0000000..fb881c6
--- /dev/null
@@ -0,0 +1,1317 @@
+/*
+    tda18271-maps.c - driver for the Philips / NXP TDA18271 silicon tuner
+
+    Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
+
+    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.
+*/
+
+#include "tda18271-priv.h"
+
+struct tda18271_pll_map {
+       u32 lomax;
+       u8 pd; /* post div */
+       u8 d;  /*      div */
+};
+
+struct tda18271_map {
+       u32 rfmax;
+       u8  val;
+};
+
+/*---------------------------------------------------------------------*/
+
+static struct tda18271_pll_map tda18271c1_main_pll[] = {
+       { .lomax =  32000, .pd = 0x5f, .d = 0xf0 },
+       { .lomax =  35000, .pd = 0x5e, .d = 0xe0 },
+       { .lomax =  37000, .pd = 0x5d, .d = 0xd0 },
+       { .lomax =  41000, .pd = 0x5c, .d = 0xc0 },
+       { .lomax =  44000, .pd = 0x5b, .d = 0xb0 },
+       { .lomax =  49000, .pd = 0x5a, .d = 0xa0 },
+       { .lomax =  54000, .pd = 0x59, .d = 0x90 },
+       { .lomax =  61000, .pd = 0x58, .d = 0x80 },
+       { .lomax =  65000, .pd = 0x4f, .d = 0x78 },
+       { .lomax =  70000, .pd = 0x4e, .d = 0x70 },
+       { .lomax =  75000, .pd = 0x4d, .d = 0x68 },
+       { .lomax =  82000, .pd = 0x4c, .d = 0x60 },
+       { .lomax =  89000, .pd = 0x4b, .d = 0x58 },
+       { .lomax =  98000, .pd = 0x4a, .d = 0x50 },
+       { .lomax = 109000, .pd = 0x49, .d = 0x48 },
+       { .lomax = 123000, .pd = 0x48, .d = 0x40 },
+       { .lomax = 131000, .pd = 0x3f, .d = 0x3c },
+       { .lomax = 141000, .pd = 0x3e, .d = 0x38 },
+       { .lomax = 151000, .pd = 0x3d, .d = 0x34 },
+       { .lomax = 164000, .pd = 0x3c, .d = 0x30 },
+       { .lomax = 179000, .pd = 0x3b, .d = 0x2c },
+       { .lomax = 197000, .pd = 0x3a, .d = 0x28 },
+       { .lomax = 219000, .pd = 0x39, .d = 0x24 },
+       { .lomax = 246000, .pd = 0x38, .d = 0x20 },
+       { .lomax = 263000, .pd = 0x2f, .d = 0x1e },
+       { .lomax = 282000, .pd = 0x2e, .d = 0x1c },
+       { .lomax = 303000, .pd = 0x2d, .d = 0x1a },
+       { .lomax = 329000, .pd = 0x2c, .d = 0x18 },
+       { .lomax = 359000, .pd = 0x2b, .d = 0x16 },
+       { .lomax = 395000, .pd = 0x2a, .d = 0x14 },
+       { .lomax = 438000, .pd = 0x29, .d = 0x12 },
+       { .lomax = 493000, .pd = 0x28, .d = 0x10 },
+       { .lomax = 526000, .pd = 0x1f, .d = 0x0f },
+       { .lomax = 564000, .pd = 0x1e, .d = 0x0e },
+       { .lomax = 607000, .pd = 0x1d, .d = 0x0d },
+       { .lomax = 658000, .pd = 0x1c, .d = 0x0c },
+       { .lomax = 718000, .pd = 0x1b, .d = 0x0b },
+       { .lomax = 790000, .pd = 0x1a, .d = 0x0a },
+       { .lomax = 877000, .pd = 0x19, .d = 0x09 },
+       { .lomax = 987000, .pd = 0x18, .d = 0x08 },
+       { .lomax =      0, .pd = 0x00, .d = 0x00 }, /* end */
+};
+
+static struct tda18271_pll_map tda18271c2_main_pll[] = {
+       { .lomax =  33125, .pd = 0x57, .d = 0xf0 },
+       { .lomax =  35500, .pd = 0x56, .d = 0xe0 },
+       { .lomax =  38188, .pd = 0x55, .d = 0xd0 },
+       { .lomax =  41375, .pd = 0x54, .d = 0xc0 },
+       { .lomax =  45125, .pd = 0x53, .d = 0xb0 },
+       { .lomax =  49688, .pd = 0x52, .d = 0xa0 },
+       { .lomax =  55188, .pd = 0x51, .d = 0x90 },
+       { .lomax =  62125, .pd = 0x50, .d = 0x80 },
+       { .lomax =  66250, .pd = 0x47, .d = 0x78 },
+       { .lomax =  71000, .pd = 0x46, .d = 0x70 },
+       { .lomax =  76375, .pd = 0x45, .d = 0x68 },
+       { .lomax =  82750, .pd = 0x44, .d = 0x60 },
+       { .lomax =  90250, .pd = 0x43, .d = 0x58 },
+       { .lomax =  99375, .pd = 0x42, .d = 0x50 },
+       { .lomax = 110375, .pd = 0x41, .d = 0x48 },
+       { .lomax = 124250, .pd = 0x40, .d = 0x40 },
+       { .lomax = 132500, .pd = 0x37, .d = 0x3c },
+       { .lomax = 142000, .pd = 0x36, .d = 0x38 },
+       { .lomax = 152750, .pd = 0x35, .d = 0x34 },
+       { .lomax = 165500, .pd = 0x34, .d = 0x30 },
+       { .lomax = 180500, .pd = 0x33, .d = 0x2c },
+       { .lomax = 198750, .pd = 0x32, .d = 0x28 },
+       { .lomax = 220750, .pd = 0x31, .d = 0x24 },
+       { .lomax = 248500, .pd = 0x30, .d = 0x20 },
+       { .lomax = 265000, .pd = 0x27, .d = 0x1e },
+       { .lomax = 284000, .pd = 0x26, .d = 0x1c },
+       { .lomax = 305500, .pd = 0x25, .d = 0x1a },
+       { .lomax = 331000, .pd = 0x24, .d = 0x18 },
+       { .lomax = 361000, .pd = 0x23, .d = 0x16 },
+       { .lomax = 397500, .pd = 0x22, .d = 0x14 },
+       { .lomax = 441500, .pd = 0x21, .d = 0x12 },
+       { .lomax = 497000, .pd = 0x20, .d = 0x10 },
+       { .lomax = 530000, .pd = 0x17, .d = 0x0f },
+       { .lomax = 568000, .pd = 0x16, .d = 0x0e },
+       { .lomax = 611000, .pd = 0x15, .d = 0x0d },
+       { .lomax = 662000, .pd = 0x14, .d = 0x0c },
+       { .lomax = 722000, .pd = 0x13, .d = 0x0b },
+       { .lomax = 795000, .pd = 0x12, .d = 0x0a },
+       { .lomax = 883000, .pd = 0x11, .d = 0x09 },
+       { .lomax = 994000, .pd = 0x10, .d = 0x08 },
+       { .lomax =      0, .pd = 0x00, .d = 0x00 }, /* end */
+};
+
+static struct tda18271_pll_map tda18271c1_cal_pll[] = {
+       { .lomax =   33000, .pd = 0xdd, .d = 0xd0 },
+       { .lomax =   36000, .pd = 0xdc, .d = 0xc0 },
+       { .lomax =   40000, .pd = 0xdb, .d = 0xb0 },
+       { .lomax =   44000, .pd = 0xda, .d = 0xa0 },
+       { .lomax =   49000, .pd = 0xd9, .d = 0x90 },
+       { .lomax =   55000, .pd = 0xd8, .d = 0x80 },
+       { .lomax =   63000, .pd = 0xd3, .d = 0x70 },
+       { .lomax =   67000, .pd = 0xcd, .d = 0x68 },
+       { .lomax =   73000, .pd = 0xcc, .d = 0x60 },
+       { .lomax =   80000, .pd = 0xcb, .d = 0x58 },
+       { .lomax =   88000, .pd = 0xca, .d = 0x50 },
+       { .lomax =   98000, .pd = 0xc9, .d = 0x48 },
+       { .lomax =  110000, .pd = 0xc8, .d = 0x40 },
+       { .lomax =  126000, .pd = 0xc3, .d = 0x38 },
+       { .lomax =  135000, .pd = 0xbd, .d = 0x34 },
+       { .lomax =  147000, .pd = 0xbc, .d = 0x30 },
+       { .lomax =  160000, .pd = 0xbb, .d = 0x2c },
+       { .lomax =  176000, .pd = 0xba, .d = 0x28 },
+       { .lomax =  196000, .pd = 0xb9, .d = 0x24 },
+       { .lomax =  220000, .pd = 0xb8, .d = 0x20 },
+       { .lomax =  252000, .pd = 0xb3, .d = 0x1c },
+       { .lomax =  271000, .pd = 0xad, .d = 0x1a },
+       { .lomax =  294000, .pd = 0xac, .d = 0x18 },
+       { .lomax =  321000, .pd = 0xab, .d = 0x16 },
+       { .lomax =  353000, .pd = 0xaa, .d = 0x14 },
+       { .lomax =  392000, .pd = 0xa9, .d = 0x12 },
+       { .lomax =  441000, .pd = 0xa8, .d = 0x10 },
+       { .lomax =  505000, .pd = 0xa3, .d = 0x0e },
+       { .lomax =  543000, .pd = 0x9d, .d = 0x0d },
+       { .lomax =  589000, .pd = 0x9c, .d = 0x0c },
+       { .lomax =  642000, .pd = 0x9b, .d = 0x0b },
+       { .lomax =  707000, .pd = 0x9a, .d = 0x0a },
+       { .lomax =  785000, .pd = 0x99, .d = 0x09 },
+       { .lomax =  883000, .pd = 0x98, .d = 0x08 },
+       { .lomax = 1010000, .pd = 0x93, .d = 0x07 },
+       { .lomax =       0, .pd = 0x00, .d = 0x00 }, /* end */
+};
+
+static struct tda18271_pll_map tda18271c2_cal_pll[] = {
+       { .lomax =   33813, .pd = 0xdd, .d = 0xd0 },
+       { .lomax =   36625, .pd = 0xdc, .d = 0xc0 },
+       { .lomax =   39938, .pd = 0xdb, .d = 0xb0 },
+       { .lomax =   43938, .pd = 0xda, .d = 0xa0 },
+       { .lomax =   48813, .pd = 0xd9, .d = 0x90 },
+       { .lomax =   54938, .pd = 0xd8, .d = 0x80 },
+       { .lomax =   62813, .pd = 0xd3, .d = 0x70 },
+       { .lomax =   67625, .pd = 0xcd, .d = 0x68 },
+       { .lomax =   73250, .pd = 0xcc, .d = 0x60 },
+       { .lomax =   79875, .pd = 0xcb, .d = 0x58 },
+       { .lomax =   87875, .pd = 0xca, .d = 0x50 },
+       { .lomax =   97625, .pd = 0xc9, .d = 0x48 },
+       { .lomax =  109875, .pd = 0xc8, .d = 0x40 },
+       { .lomax =  125625, .pd = 0xc3, .d = 0x38 },
+       { .lomax =  135250, .pd = 0xbd, .d = 0x34 },
+       { .lomax =  146500, .pd = 0xbc, .d = 0x30 },
+       { .lomax =  159750, .pd = 0xbb, .d = 0x2c },
+       { .lomax =  175750, .pd = 0xba, .d = 0x28 },
+       { .lomax =  195250, .pd = 0xb9, .d = 0x24 },
+       { .lomax =  219750, .pd = 0xb8, .d = 0x20 },
+       { .lomax =  251250, .pd = 0xb3, .d = 0x1c },
+       { .lomax =  270500, .pd = 0xad, .d = 0x1a },
+       { .lomax =  293000, .pd = 0xac, .d = 0x18 },
+       { .lomax =  319500, .pd = 0xab, .d = 0x16 },
+       { .lomax =  351500, .pd = 0xaa, .d = 0x14 },
+       { .lomax =  390500, .pd = 0xa9, .d = 0x12 },
+       { .lomax =  439500, .pd = 0xa8, .d = 0x10 },
+       { .lomax =  502500, .pd = 0xa3, .d = 0x0e },
+       { .lomax =  541000, .pd = 0x9d, .d = 0x0d },
+       { .lomax =  586000, .pd = 0x9c, .d = 0x0c },
+       { .lomax =  639000, .pd = 0x9b, .d = 0x0b },
+       { .lomax =  703000, .pd = 0x9a, .d = 0x0a },
+       { .lomax =  781000, .pd = 0x99, .d = 0x09 },
+       { .lomax =  879000, .pd = 0x98, .d = 0x08 },
+       { .lomax =       0, .pd = 0x00, .d = 0x00 }, /* end */
+};
+
+static struct tda18271_map tda18271_bp_filter[] = {
+       { .rfmax =  62000, .val = 0x00 },
+       { .rfmax =  84000, .val = 0x01 },
+       { .rfmax = 100000, .val = 0x02 },
+       { .rfmax = 140000, .val = 0x03 },
+       { .rfmax = 170000, .val = 0x04 },
+       { .rfmax = 180000, .val = 0x05 },
+       { .rfmax = 865000, .val = 0x06 },
+       { .rfmax =      0, .val = 0x00 }, /* end */
+};
+
+static struct tda18271_map tda18271c1_km[] = {
+       { .rfmax =  61100, .val = 0x74 },
+       { .rfmax = 350000, .val = 0x40 },
+       { .rfmax = 720000, .val = 0x30 },
+       { .rfmax = 865000, .val = 0x40 },
+       { .rfmax =      0, .val = 0x00 }, /* end */
+};
+
+static struct tda18271_map tda18271c2_km[] = {
+       { .rfmax =  47900, .val = 0x38 },
+       { .rfmax =  61100, .val = 0x44 },
+       { .rfmax = 350000, .val = 0x30 },
+       { .rfmax = 720000, .val = 0x24 },
+       { .rfmax = 865000, .val = 0x3c },
+       { .rfmax =      0, .val = 0x00 }, /* end */
+};
+
+static struct tda18271_map tda18271_rf_band[] = {
+       { .rfmax =  47900, .val = 0x00 },
+       { .rfmax =  61100, .val = 0x01 },
+       { .rfmax = 152600, .val = 0x02 },
+       { .rfmax = 164700, .val = 0x03 },
+       { .rfmax = 203500, .val = 0x04 },
+       { .rfmax = 457800, .val = 0x05 },
+       { .rfmax = 865000, .val = 0x06 },
+       { .rfmax =      0, .val = 0x00 }, /* end */
+};
+
+static struct tda18271_map tda18271_gain_taper[] = {
+       { .rfmax =  45400, .val = 0x1f },
+       { .rfmax =  45800, .val = 0x1e },
+       { .rfmax =  46200, .val = 0x1d },
+       { .rfmax =  46700, .val = 0x1c },
+       { .rfmax =  47100, .val = 0x1b },
+       { .rfmax =  47500, .val = 0x1a },
+       { .rfmax =  47900, .val = 0x19 },
+       { .rfmax =  49600, .val = 0x17 },
+       { .rfmax =  51200, .val = 0x16 },
+       { .rfmax =  52900, .val = 0x15 },
+       { .rfmax =  54500, .val = 0x14 },
+       { .rfmax =  56200, .val = 0x13 },
+       { .rfmax =  57800, .val = 0x12 },
+       { .rfmax =  59500, .val = 0x11 },
+       { .rfmax =  61100, .val = 0x10 },
+       { .rfmax =  67600, .val = 0x0d },
+       { .rfmax =  74200, .val = 0x0c },
+       { .rfmax =  80700, .val = 0x0b },
+       { .rfmax =  87200, .val = 0x0a },
+       { .rfmax =  93800, .val = 0x09 },
+       { .rfmax = 100300, .val = 0x08 },
+       { .rfmax = 106900, .val = 0x07 },
+       { .rfmax = 113400, .val = 0x06 },
+       { .rfmax = 119900, .val = 0x05 },
+       { .rfmax = 126500, .val = 0x04 },
+       { .rfmax = 133000, .val = 0x03 },
+       { .rfmax = 139500, .val = 0x02 },
+       { .rfmax = 146100, .val = 0x01 },
+       { .rfmax = 152600, .val = 0x00 },
+       { .rfmax = 154300, .val = 0x1f },
+       { .rfmax = 156100, .val = 0x1e },
+       { .rfmax = 157800, .val = 0x1d },
+       { .rfmax = 159500, .val = 0x1c },
+       { .rfmax = 161200, .val = 0x1b },
+       { .rfmax = 163000, .val = 0x1a },
+       { .rfmax = 164700, .val = 0x19 },
+       { .rfmax = 170200, .val = 0x17 },
+       { .rfmax = 175800, .val = 0x16 },
+       { .rfmax = 181300, .val = 0x15 },
+       { .rfmax = 186900, .val = 0x14 },
+       { .rfmax = 192400, .val = 0x13 },
+       { .rfmax = 198000, .val = 0x12 },
+       { .rfmax = 203500, .val = 0x11 },
+       { .rfmax = 216200, .val = 0x14 },
+       { .rfmax = 228900, .val = 0x13 },
+       { .rfmax = 241600, .val = 0x12 },
+       { .rfmax = 254400, .val = 0x11 },
+       { .rfmax = 267100, .val = 0x10 },
+       { .rfmax = 279800, .val = 0x0f },
+       { .rfmax = 292500, .val = 0x0e },
+       { .rfmax = 305200, .val = 0x0d },
+       { .rfmax = 317900, .val = 0x0c },
+       { .rfmax = 330700, .val = 0x0b },
+       { .rfmax = 343400, .val = 0x0a },
+       { .rfmax = 356100, .val = 0x09 },
+       { .rfmax = 368800, .val = 0x08 },
+       { .rfmax = 381500, .val = 0x07 },
+       { .rfmax = 394200, .val = 0x06 },
+       { .rfmax = 406900, .val = 0x05 },
+       { .rfmax = 419700, .val = 0x04 },
+       { .rfmax = 432400, .val = 0x03 },
+       { .rfmax = 445100, .val = 0x02 },
+       { .rfmax = 457800, .val = 0x01 },
+       { .rfmax = 476300, .val = 0x19 },
+       { .rfmax = 494800, .val = 0x18 },
+       { .rfmax = 513300, .val = 0x17 },
+       { .rfmax = 531800, .val = 0x16 },
+       { .rfmax = 550300, .val = 0x15 },
+       { .rfmax = 568900, .val = 0x14 },
+       { .rfmax = 587400, .val = 0x13 },
+       { .rfmax = 605900, .val = 0x12 },
+       { .rfmax = 624400, .val = 0x11 },
+       { .rfmax = 642900, .val = 0x10 },
+       { .rfmax = 661400, .val = 0x0f },
+       { .rfmax = 679900, .val = 0x0e },
+       { .rfmax = 698400, .val = 0x0d },
+       { .rfmax = 716900, .val = 0x0c },
+       { .rfmax = 735400, .val = 0x0b },
+       { .rfmax = 753900, .val = 0x0a },
+       { .rfmax = 772500, .val = 0x09 },
+       { .rfmax = 791000, .val = 0x08 },
+       { .rfmax = 809500, .val = 0x07 },
+       { .rfmax = 828000, .val = 0x06 },
+       { .rfmax = 846500, .val = 0x05 },
+       { .rfmax = 865000, .val = 0x04 },
+       { .rfmax =      0, .val = 0x00 }, /* end */
+};
+
+static struct tda18271_map tda18271c1_rf_cal[] = {
+       { .rfmax = 41000, .val = 0x1e },
+       { .rfmax = 43000, .val = 0x30 },
+       { .rfmax = 45000, .val = 0x43 },
+       { .rfmax = 46000, .val = 0x4d },
+       { .rfmax = 47000, .val = 0x54 },
+       { .rfmax = 47900, .val = 0x64 },
+       { .rfmax = 49100, .val = 0x20 },
+       { .rfmax = 50000, .val = 0x22 },
+       { .rfmax = 51000, .val = 0x2a },
+       { .rfmax = 53000, .val = 0x32 },
+       { .rfmax = 55000, .val = 0x35 },
+       { .rfmax = 56000, .val = 0x3c },
+       { .rfmax = 57000, .val = 0x3f },
+       { .rfmax = 58000, .val = 0x48 },
+       { .rfmax = 59000, .val = 0x4d },
+       { .rfmax = 60000, .val = 0x58 },
+       { .rfmax = 61100, .val = 0x5f },
+       { .rfmax =     0, .val = 0x00 }, /* end */
+};
+
+static struct tda18271_map tda18271c2_rf_cal[] = {
+       { .rfmax =  41000, .val = 0x0f },
+       { .rfmax =  43000, .val = 0x1c },
+       { .rfmax =  45000, .val = 0x2f },
+       { .rfmax =  46000, .val = 0x39 },
+       { .rfmax =  47000, .val = 0x40 },
+       { .rfmax =  47900, .val = 0x50 },
+       { .rfmax =  49100, .val = 0x16 },
+       { .rfmax =  50000, .val = 0x18 },
+       { .rfmax =  51000, .val = 0x20 },
+       { .rfmax =  53000, .val = 0x28 },
+       { .rfmax =  55000, .val = 0x2b },
+       { .rfmax =  56000, .val = 0x32 },
+       { .rfmax =  57000, .val = 0x35 },
+       { .rfmax =  58000, .val = 0x3e },
+       { .rfmax =  59000, .val = 0x43 },
+       { .rfmax =  60000, .val = 0x4e },
+       { .rfmax =  61100, .val = 0x55 },
+       { .rfmax =  63000, .val = 0x0f },
+       { .rfmax =  64000, .val = 0x11 },
+       { .rfmax =  65000, .val = 0x12 },
+       { .rfmax =  66000, .val = 0x15 },
+       { .rfmax =  67000, .val = 0x16 },
+       { .rfmax =  68000, .val = 0x17 },
+       { .rfmax =  70000, .val = 0x19 },
+       { .rfmax =  71000, .val = 0x1c },
+       { .rfmax =  72000, .val = 0x1d },
+       { .rfmax =  73000, .val = 0x1f },
+       { .rfmax =  74000, .val = 0x20 },
+       { .rfmax =  75000, .val = 0x21 },
+       { .rfmax =  76000, .val = 0x24 },
+       { .rfmax =  77000, .val = 0x25 },
+       { .rfmax =  78000, .val = 0x27 },
+       { .rfmax =  80000, .val = 0x28 },
+       { .rfmax =  81000, .val = 0x29 },
+       { .rfmax =  82000, .val = 0x2d },
+       { .rfmax =  83000, .val = 0x2e },
+       { .rfmax =  84000, .val = 0x2f },
+       { .rfmax =  85000, .val = 0x31 },
+       { .rfmax =  86000, .val = 0x33 },
+       { .rfmax =  87000, .val = 0x34 },
+       { .rfmax =  88000, .val = 0x35 },
+       { .rfmax =  89000, .val = 0x37 },
+       { .rfmax =  90000, .val = 0x38 },
+       { .rfmax =  91000, .val = 0x39 },
+       { .rfmax =  93000, .val = 0x3c },
+       { .rfmax =  94000, .val = 0x3e },
+       { .rfmax =  95000, .val = 0x3f },
+       { .rfmax =  96000, .val = 0x40 },
+       { .rfmax =  97000, .val = 0x42 },
+       { .rfmax =  99000, .val = 0x45 },
+       { .rfmax = 100000, .val = 0x46 },
+       { .rfmax = 102000, .val = 0x48 },
+       { .rfmax = 103000, .val = 0x4a },
+       { .rfmax = 105000, .val = 0x4d },
+       { .rfmax = 106000, .val = 0x4e },
+       { .rfmax = 107000, .val = 0x50 },
+       { .rfmax = 108000, .val = 0x51 },
+       { .rfmax = 110000, .val = 0x54 },
+       { .rfmax = 111000, .val = 0x56 },
+       { .rfmax = 112000, .val = 0x57 },
+       { .rfmax = 113000, .val = 0x58 },
+       { .rfmax = 114000, .val = 0x59 },
+       { .rfmax = 115000, .val = 0x5c },
+       { .rfmax = 116000, .val = 0x5d },
+       { .rfmax = 117000, .val = 0x5f },
+       { .rfmax = 119000, .val = 0x60 },
+       { .rfmax = 120000, .val = 0x64 },
+       { .rfmax = 121000, .val = 0x65 },
+       { .rfmax = 122000, .val = 0x66 },
+       { .rfmax = 123000, .val = 0x68 },
+       { .rfmax = 124000, .val = 0x69 },
+       { .rfmax = 125000, .val = 0x6c },
+       { .rfmax = 126000, .val = 0x6d },
+       { .rfmax = 127000, .val = 0x6e },
+       { .rfmax = 128000, .val = 0x70 },
+       { .rfmax = 129000, .val = 0x71 },
+       { .rfmax = 130000, .val = 0x75 },
+       { .rfmax = 131000, .val = 0x77 },
+       { .rfmax = 132000, .val = 0x78 },
+       { .rfmax = 133000, .val = 0x7b },
+       { .rfmax = 134000, .val = 0x7e },
+       { .rfmax = 135000, .val = 0x81 },
+       { .rfmax = 136000, .val = 0x82 },
+       { .rfmax = 137000, .val = 0x87 },
+       { .rfmax = 138000, .val = 0x88 },
+       { .rfmax = 139000, .val = 0x8d },
+       { .rfmax = 140000, .val = 0x8e },
+       { .rfmax = 141000, .val = 0x91 },
+       { .rfmax = 142000, .val = 0x95 },
+       { .rfmax = 143000, .val = 0x9a },
+       { .rfmax = 144000, .val = 0x9d },
+       { .rfmax = 145000, .val = 0xa1 },
+       { .rfmax = 146000, .val = 0xa2 },
+       { .rfmax = 147000, .val = 0xa4 },
+       { .rfmax = 148000, .val = 0xa9 },
+       { .rfmax = 149000, .val = 0xae },
+       { .rfmax = 150000, .val = 0xb0 },
+       { .rfmax = 151000, .val = 0xb1 },
+       { .rfmax = 152000, .val = 0xb7 },
+       { .rfmax = 152600, .val = 0xbd },
+       { .rfmax = 154000, .val = 0x20 },
+       { .rfmax = 155000, .val = 0x22 },
+       { .rfmax = 156000, .val = 0x24 },
+       { .rfmax = 157000, .val = 0x25 },
+       { .rfmax = 158000, .val = 0x27 },
+       { .rfmax = 159000, .val = 0x29 },
+       { .rfmax = 160000, .val = 0x2c },
+       { .rfmax = 161000, .val = 0x2d },
+       { .rfmax = 163000, .val = 0x2e },
+       { .rfmax = 164000, .val = 0x2f },
+       { .rfmax = 164700, .val = 0x30 },
+       { .rfmax = 166000, .val = 0x11 },
+       { .rfmax = 167000, .val = 0x12 },
+       { .rfmax = 168000, .val = 0x13 },
+       { .rfmax = 169000, .val = 0x14 },
+       { .rfmax = 170000, .val = 0x15 },
+       { .rfmax = 172000, .val = 0x16 },
+       { .rfmax = 173000, .val = 0x17 },
+       { .rfmax = 174000, .val = 0x18 },
+       { .rfmax = 175000, .val = 0x1a },
+       { .rfmax = 176000, .val = 0x1b },
+       { .rfmax = 178000, .val = 0x1d },
+       { .rfmax = 179000, .val = 0x1e },
+       { .rfmax = 180000, .val = 0x1f },
+       { .rfmax = 181000, .val = 0x20 },
+       { .rfmax = 182000, .val = 0x21 },
+       { .rfmax = 183000, .val = 0x22 },
+       { .rfmax = 184000, .val = 0x24 },
+       { .rfmax = 185000, .val = 0x25 },
+       { .rfmax = 186000, .val = 0x26 },
+       { .rfmax = 187000, .val = 0x27 },
+       { .rfmax = 188000, .val = 0x29 },
+       { .rfmax = 189000, .val = 0x2a },
+       { .rfmax = 190000, .val = 0x2c },
+       { .rfmax = 191000, .val = 0x2d },
+       { .rfmax = 192000, .val = 0x2e },
+       { .rfmax = 193000, .val = 0x2f },
+       { .rfmax = 194000, .val = 0x30 },
+       { .rfmax = 195000, .val = 0x33 },
+       { .rfmax = 196000, .val = 0x35 },
+       { .rfmax = 198000, .val = 0x36 },
+       { .rfmax = 200000, .val = 0x38 },
+       { .rfmax = 201000, .val = 0x3c },
+       { .rfmax = 202000, .val = 0x3d },
+       { .rfmax = 203500, .val = 0x3e },
+       { .rfmax = 206000, .val = 0x0e },
+       { .rfmax = 208000, .val = 0x0f },
+       { .rfmax = 212000, .val = 0x10 },
+       { .rfmax = 216000, .val = 0x11 },
+       { .rfmax = 217000, .val = 0x12 },
+       { .rfmax = 218000, .val = 0x13 },
+       { .rfmax = 220000, .val = 0x14 },
+       { .rfmax = 222000, .val = 0x15 },
+       { .rfmax = 225000, .val = 0x16 },
+       { .rfmax = 228000, .val = 0x17 },
+       { .rfmax = 231000, .val = 0x18 },
+       { .rfmax = 234000, .val = 0x19 },
+       { .rfmax = 235000, .val = 0x1a },
+       { .rfmax = 236000, .val = 0x1b },
+       { .rfmax = 237000, .val = 0x1c },
+       { .rfmax = 240000, .val = 0x1d },
+       { .rfmax = 242000, .val = 0x1e },
+       { .rfmax = 244000, .val = 0x1f },
+       { .rfmax = 247000, .val = 0x20 },
+       { .rfmax = 249000, .val = 0x21 },
+       { .rfmax = 252000, .val = 0x22 },
+       { .rfmax = 253000, .val = 0x23 },
+       { .rfmax = 254000, .val = 0x24 },
+       { .rfmax = 256000, .val = 0x25 },
+       { .rfmax = 259000, .val = 0x26 },
+       { .rfmax = 262000, .val = 0x27 },
+       { .rfmax = 264000, .val = 0x28 },
+       { .rfmax = 267000, .val = 0x29 },
+       { .rfmax = 269000, .val = 0x2a },
+       { .rfmax = 271000, .val = 0x2b },
+       { .rfmax = 273000, .val = 0x2c },
+       { .rfmax = 275000, .val = 0x2d },
+       { .rfmax = 277000, .val = 0x2e },
+       { .rfmax = 279000, .val = 0x2f },
+       { .rfmax = 282000, .val = 0x30 },
+       { .rfmax = 284000, .val = 0x31 },
+       { .rfmax = 286000, .val = 0x32 },
+       { .rfmax = 287000, .val = 0x33 },
+       { .rfmax = 290000, .val = 0x34 },
+       { .rfmax = 293000, .val = 0x35 },
+       { .rfmax = 295000, .val = 0x36 },
+       { .rfmax = 297000, .val = 0x37 },
+       { .rfmax = 300000, .val = 0x38 },
+       { .rfmax = 303000, .val = 0x39 },
+       { .rfmax = 305000, .val = 0x3a },
+       { .rfmax = 306000, .val = 0x3b },
+       { .rfmax = 307000, .val = 0x3c },
+       { .rfmax = 310000, .val = 0x3d },
+       { .rfmax = 312000, .val = 0x3e },
+       { .rfmax = 315000, .val = 0x3f },
+       { .rfmax = 318000, .val = 0x40 },
+       { .rfmax = 320000, .val = 0x41 },
+       { .rfmax = 323000, .val = 0x42 },
+       { .rfmax = 324000, .val = 0x43 },
+       { .rfmax = 325000, .val = 0x44 },
+       { .rfmax = 327000, .val = 0x45 },
+       { .rfmax = 331000, .val = 0x46 },
+       { .rfmax = 334000, .val = 0x47 },
+       { .rfmax = 337000, .val = 0x48 },
+       { .rfmax = 339000, .val = 0x49 },
+       { .rfmax = 340000, .val = 0x4a },
+       { .rfmax = 341000, .val = 0x4b },
+       { .rfmax = 343000, .val = 0x4c },
+       { .rfmax = 345000, .val = 0x4d },
+       { .rfmax = 349000, .val = 0x4e },
+       { .rfmax = 352000, .val = 0x4f },
+       { .rfmax = 353000, .val = 0x50 },
+       { .rfmax = 355000, .val = 0x51 },
+       { .rfmax = 357000, .val = 0x52 },
+       { .rfmax = 359000, .val = 0x53 },
+       { .rfmax = 361000, .val = 0x54 },
+       { .rfmax = 362000, .val = 0x55 },
+       { .rfmax = 364000, .val = 0x56 },
+       { .rfmax = 368000, .val = 0x57 },
+       { .rfmax = 370000, .val = 0x58 },
+       { .rfmax = 372000, .val = 0x59 },
+       { .rfmax = 375000, .val = 0x5a },
+       { .rfmax = 376000, .val = 0x5b },
+       { .rfmax = 377000, .val = 0x5c },
+       { .rfmax = 379000, .val = 0x5d },
+       { .rfmax = 382000, .val = 0x5e },
+       { .rfmax = 384000, .val = 0x5f },
+       { .rfmax = 385000, .val = 0x60 },
+       { .rfmax = 386000, .val = 0x61 },
+       { .rfmax = 388000, .val = 0x62 },
+       { .rfmax = 390000, .val = 0x63 },
+       { .rfmax = 393000, .val = 0x64 },
+       { .rfmax = 394000, .val = 0x65 },
+       { .rfmax = 396000, .val = 0x66 },
+       { .rfmax = 397000, .val = 0x67 },
+       { .rfmax = 398000, .val = 0x68 },
+       { .rfmax = 400000, .val = 0x69 },
+       { .rfmax = 402000, .val = 0x6a },
+       { .rfmax = 403000, .val = 0x6b },
+       { .rfmax = 407000, .val = 0x6c },
+       { .rfmax = 408000, .val = 0x6d },
+       { .rfmax = 409000, .val = 0x6e },
+       { .rfmax = 410000, .val = 0x6f },
+       { .rfmax = 411000, .val = 0x70 },
+       { .rfmax = 412000, .val = 0x71 },
+       { .rfmax = 413000, .val = 0x72 },
+       { .rfmax = 414000, .val = 0x73 },
+       { .rfmax = 417000, .val = 0x74 },
+       { .rfmax = 418000, .val = 0x75 },
+       { .rfmax = 420000, .val = 0x76 },
+       { .rfmax = 422000, .val = 0x77 },
+       { .rfmax = 423000, .val = 0x78 },
+       { .rfmax = 424000, .val = 0x79 },
+       { .rfmax = 427000, .val = 0x7a },
+       { .rfmax = 428000, .val = 0x7b },
+       { .rfmax = 429000, .val = 0x7d },
+       { .rfmax = 432000, .val = 0x7f },
+       { .rfmax = 434000, .val = 0x80 },
+       { .rfmax = 435000, .val = 0x81 },
+       { .rfmax = 436000, .val = 0x83 },
+       { .rfmax = 437000, .val = 0x84 },
+       { .rfmax = 438000, .val = 0x85 },
+       { .rfmax = 439000, .val = 0x86 },
+       { .rfmax = 440000, .val = 0x87 },
+       { .rfmax = 441000, .val = 0x88 },
+       { .rfmax = 442000, .val = 0x89 },
+       { .rfmax = 445000, .val = 0x8a },
+       { .rfmax = 446000, .val = 0x8b },
+       { .rfmax = 447000, .val = 0x8c },
+       { .rfmax = 448000, .val = 0x8e },
+       { .rfmax = 449000, .val = 0x8f },
+       { .rfmax = 450000, .val = 0x90 },
+       { .rfmax = 452000, .val = 0x91 },
+       { .rfmax = 453000, .val = 0x93 },
+       { .rfmax = 454000, .val = 0x94 },
+       { .rfmax = 456000, .val = 0x96 },
+       { .rfmax = 457800, .val = 0x98 },
+       { .rfmax = 461000, .val = 0x11 },
+       { .rfmax = 468000, .val = 0x12 },
+       { .rfmax = 472000, .val = 0x13 },
+       { .rfmax = 473000, .val = 0x14 },
+       { .rfmax = 474000, .val = 0x15 },
+       { .rfmax = 481000, .val = 0x16 },
+       { .rfmax = 486000, .val = 0x17 },
+       { .rfmax = 491000, .val = 0x18 },
+       { .rfmax = 498000, .val = 0x19 },
+       { .rfmax = 499000, .val = 0x1a },
+       { .rfmax = 501000, .val = 0x1b },
+       { .rfmax = 506000, .val = 0x1c },
+       { .rfmax = 511000, .val = 0x1d },
+       { .rfmax = 516000, .val = 0x1e },
+       { .rfmax = 520000, .val = 0x1f },
+       { .rfmax = 521000, .val = 0x20 },
+       { .rfmax = 525000, .val = 0x21 },
+       { .rfmax = 529000, .val = 0x22 },
+       { .rfmax = 533000, .val = 0x23 },
+       { .rfmax = 539000, .val = 0x24 },
+       { .rfmax = 541000, .val = 0x25 },
+       { .rfmax = 547000, .val = 0x26 },
+       { .rfmax = 549000, .val = 0x27 },
+       { .rfmax = 551000, .val = 0x28 },
+       { .rfmax = 556000, .val = 0x29 },
+       { .rfmax = 561000, .val = 0x2a },
+       { .rfmax = 563000, .val = 0x2b },
+       { .rfmax = 565000, .val = 0x2c },
+       { .rfmax = 569000, .val = 0x2d },
+       { .rfmax = 571000, .val = 0x2e },
+       { .rfmax = 577000, .val = 0x2f },
+       { .rfmax = 580000, .val = 0x30 },
+       { .rfmax = 582000, .val = 0x31 },
+       { .rfmax = 584000, .val = 0x32 },
+       { .rfmax = 588000, .val = 0x33 },
+       { .rfmax = 591000, .val = 0x34 },
+       { .rfmax = 596000, .val = 0x35 },
+       { .rfmax = 598000, .val = 0x36 },
+       { .rfmax = 603000, .val = 0x37 },
+       { .rfmax = 604000, .val = 0x38 },
+       { .rfmax = 606000, .val = 0x39 },
+       { .rfmax = 612000, .val = 0x3a },
+       { .rfmax = 615000, .val = 0x3b },
+       { .rfmax = 617000, .val = 0x3c },
+       { .rfmax = 621000, .val = 0x3d },
+       { .rfmax = 622000, .val = 0x3e },
+       { .rfmax = 625000, .val = 0x3f },
+       { .rfmax = 632000, .val = 0x40 },
+       { .rfmax = 633000, .val = 0x41 },
+       { .rfmax = 634000, .val = 0x42 },
+       { .rfmax = 642000, .val = 0x43 },
+       { .rfmax = 643000, .val = 0x44 },
+       { .rfmax = 647000, .val = 0x45 },
+       { .rfmax = 650000, .val = 0x46 },
+       { .rfmax = 652000, .val = 0x47 },
+       { .rfmax = 657000, .val = 0x48 },
+       { .rfmax = 661000, .val = 0x49 },
+       { .rfmax = 662000, .val = 0x4a },
+       { .rfmax = 665000, .val = 0x4b },
+       { .rfmax = 667000, .val = 0x4c },
+       { .rfmax = 670000, .val = 0x4d },
+       { .rfmax = 673000, .val = 0x4e },
+       { .rfmax = 676000, .val = 0x4f },
+       { .rfmax = 677000, .val = 0x50 },
+       { .rfmax = 681000, .val = 0x51 },
+       { .rfmax = 683000, .val = 0x52 },
+       { .rfmax = 686000, .val = 0x53 },
+       { .rfmax = 688000, .val = 0x54 },
+       { .rfmax = 689000, .val = 0x55 },
+       { .rfmax = 691000, .val = 0x56 },
+       { .rfmax = 695000, .val = 0x57 },
+       { .rfmax = 698000, .val = 0x58 },
+       { .rfmax = 703000, .val = 0x59 },
+       { .rfmax = 704000, .val = 0x5a },
+       { .rfmax = 705000, .val = 0x5b },
+       { .rfmax = 707000, .val = 0x5c },
+       { .rfmax = 710000, .val = 0x5d },
+       { .rfmax = 712000, .val = 0x5e },
+       { .rfmax = 717000, .val = 0x5f },
+       { .rfmax = 718000, .val = 0x60 },
+       { .rfmax = 721000, .val = 0x61 },
+       { .rfmax = 722000, .val = 0x62 },
+       { .rfmax = 723000, .val = 0x63 },
+       { .rfmax = 725000, .val = 0x64 },
+       { .rfmax = 727000, .val = 0x65 },
+       { .rfmax = 730000, .val = 0x66 },
+       { .rfmax = 732000, .val = 0x67 },
+       { .rfmax = 735000, .val = 0x68 },
+       { .rfmax = 740000, .val = 0x69 },
+       { .rfmax = 741000, .val = 0x6a },
+       { .rfmax = 742000, .val = 0x6b },
+       { .rfmax = 743000, .val = 0x6c },
+       { .rfmax = 745000, .val = 0x6d },
+       { .rfmax = 747000, .val = 0x6e },
+       { .rfmax = 748000, .val = 0x6f },
+       { .rfmax = 750000, .val = 0x70 },
+       { .rfmax = 752000, .val = 0x71 },
+       { .rfmax = 754000, .val = 0x72 },
+       { .rfmax = 757000, .val = 0x73 },
+       { .rfmax = 758000, .val = 0x74 },
+       { .rfmax = 760000, .val = 0x75 },
+       { .rfmax = 763000, .val = 0x76 },
+       { .rfmax = 764000, .val = 0x77 },
+       { .rfmax = 766000, .val = 0x78 },
+       { .rfmax = 767000, .val = 0x79 },
+       { .rfmax = 768000, .val = 0x7a },
+       { .rfmax = 773000, .val = 0x7b },
+       { .rfmax = 774000, .val = 0x7c },
+       { .rfmax = 776000, .val = 0x7d },
+       { .rfmax = 777000, .val = 0x7e },
+       { .rfmax = 778000, .val = 0x7f },
+       { .rfmax = 779000, .val = 0x80 },
+       { .rfmax = 781000, .val = 0x81 },
+       { .rfmax = 783000, .val = 0x82 },
+       { .rfmax = 784000, .val = 0x83 },
+       { .rfmax = 785000, .val = 0x84 },
+       { .rfmax = 786000, .val = 0x85 },
+       { .rfmax = 793000, .val = 0x86 },
+       { .rfmax = 794000, .val = 0x87 },
+       { .rfmax = 795000, .val = 0x88 },
+       { .rfmax = 797000, .val = 0x89 },
+       { .rfmax = 799000, .val = 0x8a },
+       { .rfmax = 801000, .val = 0x8b },
+       { .rfmax = 802000, .val = 0x8c },
+       { .rfmax = 803000, .val = 0x8d },
+       { .rfmax = 804000, .val = 0x8e },
+       { .rfmax = 810000, .val = 0x90 },
+       { .rfmax = 811000, .val = 0x91 },
+       { .rfmax = 812000, .val = 0x92 },
+       { .rfmax = 814000, .val = 0x93 },
+       { .rfmax = 816000, .val = 0x94 },
+       { .rfmax = 817000, .val = 0x96 },
+       { .rfmax = 818000, .val = 0x97 },
+       { .rfmax = 820000, .val = 0x98 },
+       { .rfmax = 821000, .val = 0x99 },
+       { .rfmax = 822000, .val = 0x9a },
+       { .rfmax = 828000, .val = 0x9b },
+       { .rfmax = 829000, .val = 0x9d },
+       { .rfmax = 830000, .val = 0x9f },
+       { .rfmax = 831000, .val = 0xa0 },
+       { .rfmax = 833000, .val = 0xa1 },
+       { .rfmax = 835000, .val = 0xa2 },
+       { .rfmax = 836000, .val = 0xa3 },
+       { .rfmax = 837000, .val = 0xa4 },
+       { .rfmax = 838000, .val = 0xa6 },
+       { .rfmax = 840000, .val = 0xa8 },
+       { .rfmax = 842000, .val = 0xa9 },
+       { .rfmax = 845000, .val = 0xaa },
+       { .rfmax = 846000, .val = 0xab },
+       { .rfmax = 847000, .val = 0xad },
+       { .rfmax = 848000, .val = 0xae },
+       { .rfmax = 852000, .val = 0xaf },
+       { .rfmax = 853000, .val = 0xb0 },
+       { .rfmax = 858000, .val = 0xb1 },
+       { .rfmax = 860000, .val = 0xb2 },
+       { .rfmax = 861000, .val = 0xb3 },
+       { .rfmax = 862000, .val = 0xb4 },
+       { .rfmax = 863000, .val = 0xb6 },
+       { .rfmax = 864000, .val = 0xb8 },
+       { .rfmax = 865000, .val = 0xb9 },
+       { .rfmax =      0, .val = 0x00 }, /* end */
+};
+
+static struct tda18271_map tda18271_ir_measure[] = {
+       { .rfmax =  30000, .val = 4 },
+       { .rfmax = 200000, .val = 5 },
+       { .rfmax = 600000, .val = 6 },
+       { .rfmax = 865000, .val = 7 },
+       { .rfmax =      0, .val = 0 }, /* end */
+};
+
+static struct tda18271_map tda18271_rf_cal_dc_over_dt[] = {
+       { .rfmax =  47900, .val = 0x00 },
+       { .rfmax =  55000, .val = 0x00 },
+       { .rfmax =  61100, .val = 0x0a },
+       { .rfmax =  64000, .val = 0x0a },
+       { .rfmax =  82000, .val = 0x14 },
+       { .rfmax =  84000, .val = 0x19 },
+       { .rfmax = 119000, .val = 0x1c },
+       { .rfmax = 124000, .val = 0x20 },
+       { .rfmax = 129000, .val = 0x2a },
+       { .rfmax = 134000, .val = 0x32 },
+       { .rfmax = 139000, .val = 0x39 },
+       { .rfmax = 144000, .val = 0x3e },
+       { .rfmax = 149000, .val = 0x3f },
+       { .rfmax = 152600, .val = 0x40 },
+       { .rfmax = 154000, .val = 0x40 },
+       { .rfmax = 164700, .val = 0x41 },
+       { .rfmax = 203500, .val = 0x32 },
+       { .rfmax = 353000, .val = 0x19 },
+       { .rfmax = 356000, .val = 0x1a },
+       { .rfmax = 359000, .val = 0x1b },
+       { .rfmax = 363000, .val = 0x1c },
+       { .rfmax = 366000, .val = 0x1d },
+       { .rfmax = 369000, .val = 0x1e },
+       { .rfmax = 373000, .val = 0x1f },
+       { .rfmax = 376000, .val = 0x20 },
+       { .rfmax = 379000, .val = 0x21 },
+       { .rfmax = 383000, .val = 0x22 },
+       { .rfmax = 386000, .val = 0x23 },
+       { .rfmax = 389000, .val = 0x24 },
+       { .rfmax = 393000, .val = 0x25 },
+       { .rfmax = 396000, .val = 0x26 },
+       { .rfmax = 399000, .val = 0x27 },
+       { .rfmax = 402000, .val = 0x28 },
+       { .rfmax = 404000, .val = 0x29 },
+       { .rfmax = 407000, .val = 0x2a },
+       { .rfmax = 409000, .val = 0x2b },
+       { .rfmax = 412000, .val = 0x2c },
+       { .rfmax = 414000, .val = 0x2d },
+       { .rfmax = 417000, .val = 0x2e },
+       { .rfmax = 419000, .val = 0x2f },
+       { .rfmax = 422000, .val = 0x30 },
+       { .rfmax = 424000, .val = 0x31 },
+       { .rfmax = 427000, .val = 0x32 },
+       { .rfmax = 429000, .val = 0x33 },
+       { .rfmax = 432000, .val = 0x34 },
+       { .rfmax = 434000, .val = 0x35 },
+       { .rfmax = 437000, .val = 0x36 },
+       { .rfmax = 439000, .val = 0x37 },
+       { .rfmax = 442000, .val = 0x38 },
+       { .rfmax = 444000, .val = 0x39 },
+       { .rfmax = 447000, .val = 0x3a },
+       { .rfmax = 449000, .val = 0x3b },
+       { .rfmax = 457800, .val = 0x3c },
+       { .rfmax = 465000, .val = 0x0f },
+       { .rfmax = 477000, .val = 0x12 },
+       { .rfmax = 483000, .val = 0x14 },
+       { .rfmax = 502000, .val = 0x19 },
+       { .rfmax = 508000, .val = 0x1b },
+       { .rfmax = 519000, .val = 0x1c },
+       { .rfmax = 522000, .val = 0x1d },
+       { .rfmax = 524000, .val = 0x1e },
+       { .rfmax = 534000, .val = 0x1f },
+       { .rfmax = 549000, .val = 0x20 },
+       { .rfmax = 554000, .val = 0x22 },
+       { .rfmax = 584000, .val = 0x24 },
+       { .rfmax = 589000, .val = 0x26 },
+       { .rfmax = 658000, .val = 0x27 },
+       { .rfmax = 664000, .val = 0x2c },
+       { .rfmax = 669000, .val = 0x2d },
+       { .rfmax = 699000, .val = 0x2e },
+       { .rfmax = 704000, .val = 0x30 },
+       { .rfmax = 709000, .val = 0x31 },
+       { .rfmax = 714000, .val = 0x32 },
+       { .rfmax = 724000, .val = 0x33 },
+       { .rfmax = 729000, .val = 0x36 },
+       { .rfmax = 739000, .val = 0x38 },
+       { .rfmax = 744000, .val = 0x39 },
+       { .rfmax = 749000, .val = 0x3b },
+       { .rfmax = 754000, .val = 0x3c },
+       { .rfmax = 759000, .val = 0x3d },
+       { .rfmax = 764000, .val = 0x3e },
+       { .rfmax = 769000, .val = 0x3f },
+       { .rfmax = 774000, .val = 0x40 },
+       { .rfmax = 779000, .val = 0x41 },
+       { .rfmax = 784000, .val = 0x43 },
+       { .rfmax = 789000, .val = 0x46 },
+       { .rfmax = 794000, .val = 0x48 },
+       { .rfmax = 799000, .val = 0x4b },
+       { .rfmax = 804000, .val = 0x4f },
+       { .rfmax = 809000, .val = 0x54 },
+       { .rfmax = 814000, .val = 0x59 },
+       { .rfmax = 819000, .val = 0x5d },
+       { .rfmax = 824000, .val = 0x61 },
+       { .rfmax = 829000, .val = 0x68 },
+       { .rfmax = 834000, .val = 0x6e },
+       { .rfmax = 839000, .val = 0x75 },
+       { .rfmax = 844000, .val = 0x7e },
+       { .rfmax = 849000, .val = 0x82 },
+       { .rfmax = 854000, .val = 0x84 },
+       { .rfmax = 859000, .val = 0x8f },
+       { .rfmax = 865000, .val = 0x9a },
+       { .rfmax =      0, .val = 0x00 }, /* end */
+};
+
+/*---------------------------------------------------------------------*/
+
+struct tda18271_thermo_map {
+       u8 d;
+       u8 r0;
+       u8 r1;
+};
+
+static struct tda18271_thermo_map tda18271_thermometer[] = {
+       { .d = 0x00, .r0 = 60, .r1 =  92 },
+       { .d = 0x01, .r0 = 62, .r1 =  94 },
+       { .d = 0x02, .r0 = 66, .r1 =  98 },
+       { .d = 0x03, .r0 = 64, .r1 =  96 },
+       { .d = 0x04, .r0 = 74, .r1 = 106 },
+       { .d = 0x05, .r0 = 72, .r1 = 104 },
+       { .d = 0x06, .r0 = 68, .r1 = 100 },
+       { .d = 0x07, .r0 = 70, .r1 = 102 },
+       { .d = 0x08, .r0 = 90, .r1 = 122 },
+       { .d = 0x09, .r0 = 88, .r1 = 120 },
+       { .d = 0x0a, .r0 = 84, .r1 = 116 },
+       { .d = 0x0b, .r0 = 86, .r1 = 118 },
+       { .d = 0x0c, .r0 = 76, .r1 = 108 },
+       { .d = 0x0d, .r0 = 78, .r1 = 110 },
+       { .d = 0x0e, .r0 = 82, .r1 = 114 },
+       { .d = 0x0f, .r0 = 80, .r1 = 112 },
+       { .d = 0x00, .r0 =  0, .r1 =   0 }, /* end */
+};
+
+int tda18271_lookup_thermometer(struct dvb_frontend *fe)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+       int val, i = 0;
+
+       while (tda18271_thermometer[i].d < (regs[R_TM] & 0x0f)) {
+               if (tda18271_thermometer[i + 1].d == 0)
+                       break;
+               i++;
+       }
+
+       if ((regs[R_TM] & 0x20) == 0x20)
+               val = tda18271_thermometer[i].r1;
+       else
+               val = tda18271_thermometer[i].r0;
+
+       tda_map("(%d) tm = %d\n", i, val);
+
+       return val;
+}
+
+/*---------------------------------------------------------------------*/
+
+struct tda18271_cid_target_map {
+       u32 rfmax;
+       u8  target;
+       u16 limit;
+};
+
+static struct tda18271_cid_target_map tda18271_cid_target[] = {
+       { .rfmax =  46000, .target = 0x04, .limit =  1800 },
+       { .rfmax =  52200, .target = 0x0a, .limit =  1500 },
+       { .rfmax =  70100, .target = 0x01, .limit =  4000 },
+       { .rfmax = 136800, .target = 0x18, .limit =  4000 },
+       { .rfmax = 156700, .target = 0x18, .limit =  4000 },
+       { .rfmax = 186250, .target = 0x0a, .limit =  4000 },
+       { .rfmax = 230000, .target = 0x0a, .limit =  4000 },
+       { .rfmax = 345000, .target = 0x18, .limit =  4000 },
+       { .rfmax = 426000, .target = 0x0e, .limit =  4000 },
+       { .rfmax = 489500, .target = 0x1e, .limit =  4000 },
+       { .rfmax = 697500, .target = 0x32, .limit =  4000 },
+       { .rfmax = 842000, .target = 0x3a, .limit =  4000 },
+       { .rfmax =      0, .target = 0x00, .limit =     0 }, /* end */
+};
+
+int tda18271_lookup_cid_target(struct dvb_frontend *fe,
+                              u32 *freq, u8 *cid_target, u16 *count_limit)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       int i = 0;
+
+       while ((tda18271_cid_target[i].rfmax * 1000) < *freq) {
+               if (tda18271_cid_target[i + 1].rfmax == 0)
+                       break;
+               i++;
+       }
+       *cid_target  = tda18271_cid_target[i].target;
+       *count_limit = tda18271_cid_target[i].limit;
+
+       tda_map("(%d) cid_target = %02x, count_limit = %d\n", i,
+               tda18271_cid_target[i].target, tda18271_cid_target[i].limit);
+
+       return 0;
+}
+
+/*---------------------------------------------------------------------*/
+
+static struct tda18271_rf_tracking_filter_cal tda18271_rf_band_template[] = {
+       { .rfmax =  47900, .rfband = 0x00,
+         .rf1_def =  46000, .rf2_def =      0, .rf3_def =      0 },
+       { .rfmax =  61100, .rfband = 0x01,
+         .rf1_def =  52200, .rf2_def =      0, .rf3_def =      0 },
+       { .rfmax = 152600, .rfband = 0x02,
+         .rf1_def =  70100, .rf2_def = 136800, .rf3_def =      0 },
+       { .rfmax = 164700, .rfband = 0x03,
+         .rf1_def = 156700, .rf2_def =      0, .rf3_def =      0 },
+       { .rfmax = 203500, .rfband = 0x04,
+         .rf1_def = 186250, .rf2_def =      0, .rf3_def =      0 },
+       { .rfmax = 457800, .rfband = 0x05,
+         .rf1_def = 230000, .rf2_def = 345000, .rf3_def = 426000 },
+       { .rfmax = 865000, .rfband = 0x06,
+         .rf1_def = 489500, .rf2_def = 697500, .rf3_def = 842000 },
+       { .rfmax =      0, .rfband = 0x00,
+         .rf1_def =      0, .rf2_def =      0, .rf3_def =      0 }, /* end */
+};
+
+int tda18271_lookup_rf_band(struct dvb_frontend *fe, u32 *freq, u8 *rf_band)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
+       int i = 0;
+
+       while ((map[i].rfmax * 1000) < *freq) {
+               if (tda18271_debug & DBG_ADV)
+                       tda_map("(%d) rfmax = %d < freq = %d, "
+                               "rf1_def = %d, rf2_def = %d, rf3_def = %d, "
+                               "rf1 = %d, rf2 = %d, rf3 = %d, "
+                               "rf_a1 = %d, rf_a2 = %d, "
+                               "rf_b1 = %d, rf_b2 = %d\n",
+                               i, map[i].rfmax * 1000, *freq,
+                               map[i].rf1_def, map[i].rf2_def, map[i].rf3_def,
+                               map[i].rf1, map[i].rf2, map[i].rf3,
+                               map[i].rf_a1, map[i].rf_a2,
+                               map[i].rf_b1, map[i].rf_b2);
+               if (map[i].rfmax == 0)
+                       return -EINVAL;
+               i++;
+       }
+       if (rf_band)
+               *rf_band = map[i].rfband;
+
+       tda_map("(%d) rf_band = %02x\n", i, map[i].rfband);
+
+       return i;
+}
+
+/*---------------------------------------------------------------------*/
+
+struct tda18271_map_layout {
+       struct tda18271_pll_map *main_pll;
+       struct tda18271_pll_map *cal_pll;
+
+       struct tda18271_map *rf_cal;
+       struct tda18271_map *rf_cal_kmco;
+       struct tda18271_map *rf_cal_dc_over_dt;
+
+       struct tda18271_map *bp_filter;
+       struct tda18271_map *rf_band;
+       struct tda18271_map *gain_taper;
+       struct tda18271_map *ir_measure;
+};
+
+/*---------------------------------------------------------------------*/
+
+int tda18271_lookup_pll_map(struct dvb_frontend *fe,
+                           enum tda18271_map_type map_type,
+                           u32 *freq, u8 *post_div, u8 *div)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       struct tda18271_pll_map *map = NULL;
+       unsigned int i = 0;
+       char *map_name;
+       int ret = 0;
+
+       BUG_ON(!priv->maps);
+
+       switch (map_type) {
+       case MAIN_PLL:
+               map = priv->maps->main_pll;
+               map_name = "main_pll";
+               break;
+       case CAL_PLL:
+               map = priv->maps->cal_pll;
+               map_name = "cal_pll";
+               break;
+       default:
+               /* we should never get here */
+               map_name = "undefined";
+               break;
+       }
+
+       if (!map) {
+               tda_warn("%s map is not set!\n", map_name);
+               ret = -EINVAL;
+               goto fail;
+       }
+
+       while ((map[i].lomax * 1000) < *freq) {
+               if (map[i + 1].lomax == 0) {
+                       tda_map("%s: frequency (%d) out of range\n",
+                               map_name, *freq);
+                       ret = -ERANGE;
+                       break;
+               }
+               i++;
+       }
+       *post_div = map[i].pd;
+       *div      = map[i].d;
+
+       tda_map("(%d) %s: post div = 0x%02x, div = 0x%02x\n",
+               i, map_name, *post_div, *div);
+fail:
+       return ret;
+}
+
+int tda18271_lookup_map(struct dvb_frontend *fe,
+                       enum tda18271_map_type map_type,
+                       u32 *freq, u8 *val)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       struct tda18271_map *map = NULL;
+       unsigned int i = 0;
+       char *map_name;
+       int ret = 0;
+
+       BUG_ON(!priv->maps);
+
+       switch (map_type) {
+       case BP_FILTER:
+               map = priv->maps->bp_filter;
+               map_name = "bp_filter";
+               break;
+       case RF_CAL_KMCO:
+               map = priv->maps->rf_cal_kmco;
+               map_name = "km";
+               break;
+       case RF_BAND:
+               map = priv->maps->rf_band;
+               map_name = "rf_band";
+               break;
+       case GAIN_TAPER:
+               map = priv->maps->gain_taper;
+               map_name = "gain_taper";
+               break;
+       case RF_CAL:
+               map = priv->maps->rf_cal;
+               map_name = "rf_cal";
+               break;
+       case IR_MEASURE:
+               map = priv->maps->ir_measure;
+               map_name = "ir_measure";
+               break;
+       case RF_CAL_DC_OVER_DT:
+               map = priv->maps->rf_cal_dc_over_dt;
+               map_name = "rf_cal_dc_over_dt";
+               break;
+       default:
+               /* we should never get here */
+               map_name = "undefined";
+               break;
+       }
+
+       if (!map) {
+               tda_warn("%s map is not set!\n", map_name);
+               ret = -EINVAL;
+               goto fail;
+       }
+
+       while ((map[i].rfmax * 1000) < *freq) {
+               if (map[i + 1].rfmax == 0) {
+                       tda_map("%s: frequency (%d) out of range\n",
+                               map_name, *freq);
+                       ret = -ERANGE;
+                       break;
+               }
+               i++;
+       }
+       *val = map[i].val;
+
+       tda_map("(%d) %s: 0x%02x\n", i, map_name, *val);
+fail:
+       return ret;
+}
+
+/*---------------------------------------------------------------------*/
+
+static struct tda18271_std_map tda18271c1_std_map = {
+       .fm_radio = { .if_freq = 1250, .fm_rfn = 1, .agc_mode = 3, .std = 0,
+                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x18 */
+       .atv_b    = { .if_freq = 6750, .fm_rfn = 0, .agc_mode = 1, .std = 6,
+                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
+       .atv_dk   = { .if_freq = 7750, .fm_rfn = 0, .agc_mode = 1, .std = 7,
+                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
+       .atv_gh   = { .if_freq = 7750, .fm_rfn = 0, .agc_mode = 1, .std = 7,
+                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
+       .atv_i    = { .if_freq = 7750, .fm_rfn = 0, .agc_mode = 1, .std = 7,
+                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
+       .atv_l    = { .if_freq = 7750, .fm_rfn = 0, .agc_mode = 1, .std = 7,
+                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
+       .atv_lc   = { .if_freq = 1250, .fm_rfn = 0, .agc_mode = 1, .std = 7,
+                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
+       .atv_mn   = { .if_freq = 5750, .fm_rfn = 0, .agc_mode = 1, .std = 5,
+                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0d */
+       .atsc_6   = { .if_freq = 3250, .fm_rfn = 0, .agc_mode = 3, .std = 4,
+                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
+       .dvbt_6   = { .if_freq = 3300, .fm_rfn = 0, .agc_mode = 3, .std = 4,
+                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
+       .dvbt_7   = { .if_freq = 3800, .fm_rfn = 0, .agc_mode = 3, .std = 5,
+                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1d */
+       .dvbt_8   = { .if_freq = 4300, .fm_rfn = 0, .agc_mode = 3, .std = 6,
+                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1e */
+       .qam_6    = { .if_freq = 4000, .fm_rfn = 0, .agc_mode = 3, .std = 5,
+                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1d */
+       .qam_7    = { .if_freq = 4500, .fm_rfn = 0, .agc_mode = 3, .std = 6,
+                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1e */
+       .qam_8    = { .if_freq = 5000, .fm_rfn = 0, .agc_mode = 3, .std = 7,
+                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1f */
+};
+
+static struct tda18271_std_map tda18271c2_std_map = {
+       .fm_radio = { .if_freq = 1250, .fm_rfn = 1, .agc_mode = 3, .std = 0,
+                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x18 */
+       .atv_b    = { .if_freq = 6000, .fm_rfn = 0, .agc_mode = 1, .std = 5,
+                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0d */
+       .atv_dk   = { .if_freq = 6900, .fm_rfn = 0, .agc_mode = 1, .std = 6,
+                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
+       .atv_gh   = { .if_freq = 7100, .fm_rfn = 0, .agc_mode = 1, .std = 6,
+                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
+       .atv_i    = { .if_freq = 7250, .fm_rfn = 0, .agc_mode = 1, .std = 6,
+                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
+       .atv_l    = { .if_freq = 6900, .fm_rfn = 0, .agc_mode = 1, .std = 6,
+                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
+       .atv_lc   = { .if_freq = 1250, .fm_rfn = 0, .agc_mode = 1, .std = 6,
+                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
+       .atv_mn   = { .if_freq = 5400, .fm_rfn = 0, .agc_mode = 1, .std = 4,
+                     .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0c */
+       .atsc_6   = { .if_freq = 3250, .fm_rfn = 0, .agc_mode = 3, .std = 4,
+                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
+       .dvbt_6   = { .if_freq = 3300, .fm_rfn = 0, .agc_mode = 3, .std = 4,
+                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
+       .dvbt_7   = { .if_freq = 3500, .fm_rfn = 0, .agc_mode = 3, .std = 4,
+                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
+       .dvbt_8   = { .if_freq = 4000, .fm_rfn = 0, .agc_mode = 3, .std = 5,
+                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1d */
+       .qam_6    = { .if_freq = 4000, .fm_rfn = 0, .agc_mode = 3, .std = 5,
+                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1d */
+       .qam_7    = { .if_freq = 4500, .fm_rfn = 0, .agc_mode = 3, .std = 6,
+                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1e */
+       .qam_8    = { .if_freq = 5000, .fm_rfn = 0, .agc_mode = 3, .std = 7,
+                     .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1f */
+};
+
+/*---------------------------------------------------------------------*/
+
+static struct tda18271_map_layout tda18271c1_map_layout = {
+       .main_pll          = tda18271c1_main_pll,
+       .cal_pll           = tda18271c1_cal_pll,
+
+       .rf_cal            = tda18271c1_rf_cal,
+       .rf_cal_kmco       = tda18271c1_km,
+
+       .bp_filter         = tda18271_bp_filter,
+       .rf_band           = tda18271_rf_band,
+       .gain_taper        = tda18271_gain_taper,
+       .ir_measure        = tda18271_ir_measure,
+};
+
+static struct tda18271_map_layout tda18271c2_map_layout = {
+       .main_pll          = tda18271c2_main_pll,
+       .cal_pll           = tda18271c2_cal_pll,
+
+       .rf_cal            = tda18271c2_rf_cal,
+       .rf_cal_kmco       = tda18271c2_km,
+
+       .rf_cal_dc_over_dt = tda18271_rf_cal_dc_over_dt,
+
+       .bp_filter         = tda18271_bp_filter,
+       .rf_band           = tda18271_rf_band,
+       .gain_taper        = tda18271_gain_taper,
+       .ir_measure        = tda18271_ir_measure,
+};
+
+int tda18271_assign_map_layout(struct dvb_frontend *fe)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       int ret = 0;
+
+       switch (priv->id) {
+       case TDA18271HDC1:
+               priv->maps = &tda18271c1_map_layout;
+               memcpy(&priv->std, &tda18271c1_std_map,
+                      sizeof(struct tda18271_std_map));
+               break;
+       case TDA18271HDC2:
+               priv->maps = &tda18271c2_map_layout;
+               memcpy(&priv->std, &tda18271c2_std_map,
+                      sizeof(struct tda18271_std_map));
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+       memcpy(priv->rf_cal_state, &tda18271_rf_band_template,
+              sizeof(tda18271_rf_band_template));
+
+       return ret;
+}
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/tuners/tda18271-priv.h b/drivers/media/tuners/tda18271-priv.h
new file mode 100644 (file)
index 0000000..454c152
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+    tda18271-priv.h - private header for the NXP TDA18271 silicon tuner
+
+    Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
+
+    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 __TDA18271_PRIV_H__
+#define __TDA18271_PRIV_H__
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include "tuner-i2c.h"
+#include "tda18271.h"
+
+#define R_ID     0x00  /* ID byte                */
+#define R_TM     0x01  /* Thermo byte            */
+#define R_PL     0x02  /* Power level byte       */
+#define R_EP1    0x03  /* Easy Prog byte 1       */
+#define R_EP2    0x04  /* Easy Prog byte 2       */
+#define R_EP3    0x05  /* Easy Prog byte 3       */
+#define R_EP4    0x06  /* Easy Prog byte 4       */
+#define R_EP5    0x07  /* Easy Prog byte 5       */
+#define R_CPD    0x08  /* Cal Post-Divider byte  */
+#define R_CD1    0x09  /* Cal Divider byte 1     */
+#define R_CD2    0x0a  /* Cal Divider byte 2     */
+#define R_CD3    0x0b  /* Cal Divider byte 3     */
+#define R_MPD    0x0c  /* Main Post-Divider byte */
+#define R_MD1    0x0d  /* Main Divider byte 1    */
+#define R_MD2    0x0e  /* Main Divider byte 2    */
+#define R_MD3    0x0f  /* Main Divider byte 3    */
+#define R_EB1    0x10  /* Extended byte 1        */
+#define R_EB2    0x11  /* Extended byte 2        */
+#define R_EB3    0x12  /* Extended byte 3        */
+#define R_EB4    0x13  /* Extended byte 4        */
+#define R_EB5    0x14  /* Extended byte 5        */
+#define R_EB6    0x15  /* Extended byte 6        */
+#define R_EB7    0x16  /* Extended byte 7        */
+#define R_EB8    0x17  /* Extended byte 8        */
+#define R_EB9    0x18  /* Extended byte 9        */
+#define R_EB10   0x19  /* Extended byte 10       */
+#define R_EB11   0x1a  /* Extended byte 11       */
+#define R_EB12   0x1b  /* Extended byte 12       */
+#define R_EB13   0x1c  /* Extended byte 13       */
+#define R_EB14   0x1d  /* Extended byte 14       */
+#define R_EB15   0x1e  /* Extended byte 15       */
+#define R_EB16   0x1f  /* Extended byte 16       */
+#define R_EB17   0x20  /* Extended byte 17       */
+#define R_EB18   0x21  /* Extended byte 18       */
+#define R_EB19   0x22  /* Extended byte 19       */
+#define R_EB20   0x23  /* Extended byte 20       */
+#define R_EB21   0x24  /* Extended byte 21       */
+#define R_EB22   0x25  /* Extended byte 22       */
+#define R_EB23   0x26  /* Extended byte 23       */
+
+#define TDA18271_NUM_REGS 39
+
+/*---------------------------------------------------------------------*/
+
+struct tda18271_rf_tracking_filter_cal {
+       u32 rfmax;
+       u8  rfband;
+       u32 rf1_def;
+       u32 rf2_def;
+       u32 rf3_def;
+       u32 rf1;
+       u32 rf2;
+       u32 rf3;
+       s32 rf_a1;
+       s32 rf_b1;
+       s32 rf_a2;
+       s32 rf_b2;
+};
+
+enum tda18271_pll {
+       TDA18271_MAIN_PLL,
+       TDA18271_CAL_PLL,
+};
+
+struct tda18271_map_layout;
+
+enum tda18271_ver {
+       TDA18271HDC1,
+       TDA18271HDC2,
+};
+
+struct tda18271_priv {
+       unsigned char tda18271_regs[TDA18271_NUM_REGS];
+
+       struct list_head        hybrid_tuner_instance_list;
+       struct tuner_i2c_props  i2c_props;
+
+       enum tda18271_mode mode;
+       enum tda18271_role role;
+       enum tda18271_i2c_gate gate;
+       enum tda18271_ver id;
+       enum tda18271_output_options output_opt;
+       enum tda18271_small_i2c small_i2c;
+
+       unsigned int config; /* interface to saa713x / tda829x */
+       unsigned int cal_initialized:1;
+
+       u8 tm_rfcal;
+
+       struct tda18271_map_layout *maps;
+       struct tda18271_std_map std;
+       struct tda18271_rf_tracking_filter_cal rf_cal_state[8];
+
+       struct mutex lock;
+
+       u16 if_freq;
+
+       u32 frequency;
+       u32 bandwidth;
+};
+
+/*---------------------------------------------------------------------*/
+
+extern int tda18271_debug;
+
+#define DBG_INFO 1
+#define DBG_MAP  2
+#define DBG_REG  4
+#define DBG_ADV  8
+#define DBG_CAL  16
+
+__attribute__((format(printf, 4, 5)))
+int _tda_printk(struct tda18271_priv *state, const char *level,
+               const char *func, const char *fmt, ...);
+
+#define tda_printk(st, lvl, fmt, arg...)                       \
+       _tda_printk(st, lvl, __func__, fmt, ##arg)
+
+#define tda_dprintk(st, lvl, fmt, arg...)                      \
+do {                                                           \
+       if (tda18271_debug & lvl)                               \
+               tda_printk(st, KERN_DEBUG, fmt, ##arg);         \
+} while (0)
+
+#define tda_info(fmt, arg...)  pr_info(fmt, ##arg)
+#define tda_warn(fmt, arg...)  tda_printk(priv, KERN_WARNING, fmt, ##arg)
+#define tda_err(fmt, arg...)   tda_printk(priv, KERN_ERR,     fmt, ##arg)
+#define tda_dbg(fmt, arg...)   tda_dprintk(priv, DBG_INFO,    fmt, ##arg)
+#define tda_map(fmt, arg...)   tda_dprintk(priv, DBG_MAP,     fmt, ##arg)
+#define tda_reg(fmt, arg...)   tda_dprintk(priv, DBG_REG,     fmt, ##arg)
+#define tda_cal(fmt, arg...)   tda_dprintk(priv, DBG_CAL,     fmt, ##arg)
+
+#define tda_fail(ret)                                                       \
+({                                                                          \
+       int __ret;                                                           \
+       __ret = (ret < 0);                                                   \
+       if (__ret)                                                           \
+               tda_printk(priv, KERN_ERR,                                   \
+                          "error %d on line %d\n", ret, __LINE__);          \
+       __ret;                                                               \
+})
+
+/*---------------------------------------------------------------------*/
+
+enum tda18271_map_type {
+       /* tda18271_pll_map */
+       MAIN_PLL,
+       CAL_PLL,
+       /* tda18271_map */
+       RF_CAL,
+       RF_CAL_KMCO,
+       RF_CAL_DC_OVER_DT,
+       BP_FILTER,
+       RF_BAND,
+       GAIN_TAPER,
+       IR_MEASURE,
+};
+
+extern int tda18271_lookup_pll_map(struct dvb_frontend *fe,
+                                  enum tda18271_map_type map_type,
+                                  u32 *freq, u8 *post_div, u8 *div);
+extern int tda18271_lookup_map(struct dvb_frontend *fe,
+                              enum tda18271_map_type map_type,
+                              u32 *freq, u8 *val);
+
+extern int tda18271_lookup_thermometer(struct dvb_frontend *fe);
+
+extern int tda18271_lookup_rf_band(struct dvb_frontend *fe,
+                                  u32 *freq, u8 *rf_band);
+
+extern int tda18271_lookup_cid_target(struct dvb_frontend *fe,
+                                     u32 *freq, u8 *cid_target,
+                                     u16 *count_limit);
+
+extern int tda18271_assign_map_layout(struct dvb_frontend *fe);
+
+/*---------------------------------------------------------------------*/
+
+extern int tda18271_read_regs(struct dvb_frontend *fe);
+extern int tda18271_read_extended(struct dvb_frontend *fe);
+extern int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len);
+extern int tda18271_init_regs(struct dvb_frontend *fe);
+
+extern int tda18271_charge_pump_source(struct dvb_frontend *fe,
+                                      enum tda18271_pll pll, int force);
+extern int tda18271_set_standby_mode(struct dvb_frontend *fe,
+                                    int sm, int sm_lt, int sm_xt);
+
+extern int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq);
+extern int tda18271_calc_cal_pll(struct dvb_frontend *fe, u32 freq);
+
+extern int tda18271_calc_bp_filter(struct dvb_frontend *fe, u32 *freq);
+extern int tda18271_calc_km(struct dvb_frontend *fe, u32 *freq);
+extern int tda18271_calc_rf_band(struct dvb_frontend *fe, u32 *freq);
+extern int tda18271_calc_gain_taper(struct dvb_frontend *fe, u32 *freq);
+extern int tda18271_calc_ir_measure(struct dvb_frontend *fe, u32 *freq);
+extern int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq);
+
+#endif /* __TDA18271_PRIV_H__ */
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/tuners/tda18271.h b/drivers/media/tuners/tda18271.h
new file mode 100644 (file)
index 0000000..640bae4
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+    tda18271.h - header for the Philips / NXP TDA18271 silicon tuner
+
+    Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
+
+    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 __TDA18271_H__
+#define __TDA18271_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+struct tda18271_std_map_item {
+       u16 if_freq;
+
+       /* EP3[4:3] */
+       unsigned int agc_mode:2;
+       /* EP3[2:0] */
+       unsigned int std:3;
+       /* EP4[7] */
+       unsigned int fm_rfn:1;
+       /* EP4[4:2] */
+       unsigned int if_lvl:3;
+       /* EB22[6:0] */
+       unsigned int rfagc_top:7;
+};
+
+struct tda18271_std_map {
+       struct tda18271_std_map_item fm_radio;
+       struct tda18271_std_map_item atv_b;
+       struct tda18271_std_map_item atv_dk;
+       struct tda18271_std_map_item atv_gh;
+       struct tda18271_std_map_item atv_i;
+       struct tda18271_std_map_item atv_l;
+       struct tda18271_std_map_item atv_lc;
+       struct tda18271_std_map_item atv_mn;
+       struct tda18271_std_map_item atsc_6;
+       struct tda18271_std_map_item dvbt_6;
+       struct tda18271_std_map_item dvbt_7;
+       struct tda18271_std_map_item dvbt_8;
+       struct tda18271_std_map_item qam_6;
+       struct tda18271_std_map_item qam_7;
+       struct tda18271_std_map_item qam_8;
+};
+
+enum tda18271_role {
+       TDA18271_MASTER = 0,
+       TDA18271_SLAVE,
+};
+
+enum tda18271_i2c_gate {
+       TDA18271_GATE_AUTO = 0,
+       TDA18271_GATE_ANALOG,
+       TDA18271_GATE_DIGITAL,
+};
+
+enum tda18271_output_options {
+       /* slave tuner output & loop thru & xtal oscillator always on */
+       TDA18271_OUTPUT_LT_XT_ON = 0,
+
+       /* slave tuner output loop thru off */
+       TDA18271_OUTPUT_LT_OFF = 1,
+
+       /* xtal oscillator off */
+       TDA18271_OUTPUT_XT_OFF = 2,
+};
+
+enum tda18271_small_i2c {
+       TDA18271_39_BYTE_CHUNK_INIT = 0,
+       TDA18271_16_BYTE_CHUNK_INIT = 16,
+       TDA18271_08_BYTE_CHUNK_INIT = 8,
+       TDA18271_03_BYTE_CHUNK_INIT = 3,
+};
+
+struct tda18271_config {
+       /* override default if freq / std settings (optional) */
+       struct tda18271_std_map *std_map;
+
+       /* master / slave tuner: master uses main pll, slave uses cal pll */
+       enum tda18271_role role;
+
+       /* use i2c gate provided by analog or digital demod */
+       enum tda18271_i2c_gate gate;
+
+       /* output options that can be disabled */
+       enum tda18271_output_options output_opt;
+
+       /* some i2c providers can't write all 39 registers at once */
+       enum tda18271_small_i2c small_i2c;
+
+       /* force rf tracking filter calibration on startup */
+       unsigned int rf_cal_on_startup:1;
+
+       /* interface to saa713x / tda829x */
+       unsigned int config;
+};
+
+#define TDA18271_CALLBACK_CMD_AGC_ENABLE 0
+
+enum tda18271_mode {
+       TDA18271_ANALOG = 0,
+       TDA18271_DIGITAL,
+};
+
+#if defined(CONFIG_MEDIA_TUNER_TDA18271) || (defined(CONFIG_MEDIA_TUNER_TDA18271_MODULE) && defined(MODULE))
+extern struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
+                                           struct i2c_adapter *i2c,
+                                           struct tda18271_config *cfg);
+#else
+static inline struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe,
+                                                  u8 addr,
+                                                  struct i2c_adapter *i2c,
+                                                  struct tda18271_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* __TDA18271_H__ */
diff --git a/drivers/media/tuners/tda827x.c b/drivers/media/tuners/tda827x.c
new file mode 100644 (file)
index 0000000..a0d1762
--- /dev/null
@@ -0,0 +1,917 @@
+/*
+ *
+ * (c) 2005 Hartmut Hackmann
+ * (c) 2007 Michael Krufky
+ *
+ *  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.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <asm/types.h>
+#include <linux/dvb/frontend.h>
+#include <linux/videodev2.h>
+
+#include "tda827x.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+#define dprintk(args...) \
+       do {                                        \
+               if (debug) printk(KERN_DEBUG "tda827x: " args); \
+       } while (0)
+
+struct tda827x_priv {
+       int i2c_addr;
+       struct i2c_adapter *i2c_adap;
+       struct tda827x_config *cfg;
+
+       unsigned int sgIF;
+       unsigned char lpsel;
+
+       u32 frequency;
+       u32 bandwidth;
+};
+
+static void tda827x_set_std(struct dvb_frontend *fe,
+                           struct analog_parameters *params)
+{
+       struct tda827x_priv *priv = fe->tuner_priv;
+       char *mode;
+
+       priv->lpsel = 0;
+       if (params->std & V4L2_STD_MN) {
+               priv->sgIF = 92;
+               priv->lpsel = 1;
+               mode = "MN";
+       } else if (params->std & V4L2_STD_B) {
+               priv->sgIF = 108;
+               mode = "B";
+       } else if (params->std & V4L2_STD_GH) {
+               priv->sgIF = 124;
+               mode = "GH";
+       } else if (params->std & V4L2_STD_PAL_I) {
+               priv->sgIF = 124;
+               mode = "I";
+       } else if (params->std & V4L2_STD_DK) {
+               priv->sgIF = 124;
+               mode = "DK";
+       } else if (params->std & V4L2_STD_SECAM_L) {
+               priv->sgIF = 124;
+               mode = "L";
+       } else if (params->std & V4L2_STD_SECAM_LC) {
+               priv->sgIF = 20;
+               mode = "LC";
+       } else {
+               priv->sgIF = 124;
+               mode = "xx";
+       }
+
+       if (params->mode == V4L2_TUNER_RADIO) {
+               priv->sgIF = 88; /* if frequency is 5.5 MHz */
+               dprintk("setting tda827x to radio FM\n");
+       } else
+               dprintk("setting tda827x to system %s\n", mode);
+}
+
+
+/* ------------------------------------------------------------------ */
+
+struct tda827x_data {
+       u32 lomax;
+       u8  spd;
+       u8  bs;
+       u8  bp;
+       u8  cp;
+       u8  gc3;
+       u8 div1p5;
+};
+
+static const struct tda827x_data tda827x_table[] = {
+       { .lomax =  62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
+       { .lomax =  66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
+       { .lomax =  76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
+       { .lomax =  84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
+       { .lomax =  93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
+       { .lomax =  98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
+       { .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
+       { .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
+       { .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
+       { .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
+       { .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
+       { .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0},
+       { .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
+       { .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
+       { .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
+       { .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
+       { .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
+       { .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
+       { .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
+       { .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
+       { .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
+       { .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
+       { .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
+       { .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
+       { .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
+       { .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
+       { .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
+       { .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
+       { .lomax =         0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}
+};
+
+static int tuner_transfer(struct dvb_frontend *fe,
+                         struct i2c_msg *msg,
+                         const int size)
+{
+       int rc;
+       struct tda827x_priv *priv = fe->tuner_priv;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+       rc = i2c_transfer(priv->i2c_adap, msg, size);
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       if (rc >= 0 && rc != size)
+               return -EIO;
+
+       return rc;
+}
+
+static int tda827xo_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct tda827x_priv *priv = fe->tuner_priv;
+       u8 buf[14];
+       int rc;
+
+       struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
+                              .buf = buf, .len = sizeof(buf) };
+       int i, tuner_freq, if_freq;
+       u32 N;
+
+       dprintk("%s:\n", __func__);
+       if (c->bandwidth_hz == 0) {
+               if_freq = 5000000;
+       } else if (c->bandwidth_hz <= 6000000) {
+               if_freq = 4000000;
+       } else if (c->bandwidth_hz <= 7000000) {
+               if_freq = 4500000;
+       } else {        /* 8 MHz */
+               if_freq = 5000000;
+       }
+       tuner_freq = c->frequency;
+
+       i = 0;
+       while (tda827x_table[i].lomax < tuner_freq) {
+               if (tda827x_table[i + 1].lomax == 0)
+                       break;
+               i++;
+       }
+
+       tuner_freq += if_freq;
+
+       N = ((tuner_freq + 125000) / 250000) << (tda827x_table[i].spd + 2);
+       buf[0] = 0;
+       buf[1] = (N>>8) | 0x40;
+       buf[2] = N & 0xff;
+       buf[3] = 0;
+       buf[4] = 0x52;
+       buf[5] = (tda827x_table[i].spd << 6) + (tda827x_table[i].div1p5 << 5) +
+                               (tda827x_table[i].bs << 3) +
+                               tda827x_table[i].bp;
+       buf[6] = (tda827x_table[i].gc3 << 4) + 0x8f;
+       buf[7] = 0xbf;
+       buf[8] = 0x2a;
+       buf[9] = 0x05;
+       buf[10] = 0xff;
+       buf[11] = 0x00;
+       buf[12] = 0x00;
+       buf[13] = 0x40;
+
+       msg.len = 14;
+       rc = tuner_transfer(fe, &msg, 1);
+       if (rc < 0)
+               goto err;
+
+       msleep(500);
+       /* correct CP value */
+       buf[0] = 0x30;
+       buf[1] = 0x50 + tda827x_table[i].cp;
+       msg.len = 2;
+
+       rc = tuner_transfer(fe, &msg, 1);
+       if (rc < 0)
+               goto err;
+
+       priv->frequency = c->frequency;
+       priv->bandwidth = c->bandwidth_hz;
+
+       return 0;
+
+err:
+       printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
+              __func__, priv->i2c_addr << 1);
+       return rc;
+}
+
+static int tda827xo_sleep(struct dvb_frontend *fe)
+{
+       struct tda827x_priv *priv = fe->tuner_priv;
+       static u8 buf[] = { 0x30, 0xd0 };
+       struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
+                              .buf = buf, .len = sizeof(buf) };
+
+       dprintk("%s:\n", __func__);
+       tuner_transfer(fe, &msg, 1);
+
+       if (priv->cfg && priv->cfg->sleep)
+               priv->cfg->sleep(fe);
+
+       return 0;
+}
+
+/* ------------------------------------------------------------------ */
+
+static int tda827xo_set_analog_params(struct dvb_frontend *fe,
+                                     struct analog_parameters *params)
+{
+       unsigned char tuner_reg[8];
+       unsigned char reg2[2];
+       u32 N;
+       int i;
+       struct tda827x_priv *priv = fe->tuner_priv;
+       struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0 };
+       unsigned int freq = params->frequency;
+
+       tda827x_set_std(fe, params);
+
+       if (params->mode == V4L2_TUNER_RADIO)
+               freq = freq / 1000;
+
+       N = freq + priv->sgIF;
+
+       i = 0;
+       while (tda827x_table[i].lomax < N * 62500) {
+               if (tda827x_table[i + 1].lomax == 0)
+                       break;
+               i++;
+       }
+
+       N = N << tda827x_table[i].spd;
+
+       tuner_reg[0] = 0;
+       tuner_reg[1] = (unsigned char)(N>>8);
+       tuner_reg[2] = (unsigned char) N;
+       tuner_reg[3] = 0x40;
+       tuner_reg[4] = 0x52 + (priv->lpsel << 5);
+       tuner_reg[5] = (tda827x_table[i].spd    << 6) +
+                      (tda827x_table[i].div1p5 << 5) +
+                      (tda827x_table[i].bs     << 3) + tda827x_table[i].bp;
+       tuner_reg[6] = 0x8f + (tda827x_table[i].gc3 << 4);
+       tuner_reg[7] = 0x8f;
+
+       msg.buf = tuner_reg;
+       msg.len = 8;
+       tuner_transfer(fe, &msg, 1);
+
+       msg.buf = reg2;
+       msg.len = 2;
+       reg2[0] = 0x80;
+       reg2[1] = 0;
+       tuner_transfer(fe, &msg, 1);
+
+       reg2[0] = 0x60;
+       reg2[1] = 0xbf;
+       tuner_transfer(fe, &msg, 1);
+
+       reg2[0] = 0x30;
+       reg2[1] = tuner_reg[4] + 0x80;
+       tuner_transfer(fe, &msg, 1);
+
+       msleep(1);
+       reg2[0] = 0x30;
+       reg2[1] = tuner_reg[4] + 4;
+       tuner_transfer(fe, &msg, 1);
+
+       msleep(1);
+       reg2[0] = 0x30;
+       reg2[1] = tuner_reg[4];
+       tuner_transfer(fe, &msg, 1);
+
+       msleep(550);
+       reg2[0] = 0x30;
+       reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp;
+       tuner_transfer(fe, &msg, 1);
+
+       reg2[0] = 0x60;
+       reg2[1] = 0x3f;
+       tuner_transfer(fe, &msg, 1);
+
+       reg2[0] = 0x80;
+       reg2[1] = 0x08;   /* Vsync en */
+       tuner_transfer(fe, &msg, 1);
+
+       priv->frequency = params->frequency;
+
+       return 0;
+}
+
+static void tda827xo_agcf(struct dvb_frontend *fe)
+{
+       struct tda827x_priv *priv = fe->tuner_priv;
+       unsigned char data[] = { 0x80, 0x0c };
+       struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
+                              .buf = data, .len = 2};
+
+       tuner_transfer(fe, &msg, 1);
+}
+
+/* ------------------------------------------------------------------ */
+
+struct tda827xa_data {
+       u32 lomax;
+       u8  svco;
+       u8  spd;
+       u8  scr;
+       u8  sbs;
+       u8  gc3;
+};
+
+static struct tda827xa_data tda827xa_dvbt[] = {
+       { .lomax =  56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
+       { .lomax =  67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
+       { .lomax =  81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
+       { .lomax =  97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
+       { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
+       { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
+       { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
+       { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
+       { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
+       { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
+       { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
+       { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
+       { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
+       { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
+       { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
+       { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
+       { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
+       { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
+       { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
+       { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
+       { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
+       { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
+       { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
+       { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
+       { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
+       { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
+       { .lomax =         0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
+};
+
+static struct tda827xa_data tda827xa_dvbc[] = {
+       { .lomax =  50125000, .svco = 2, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
+       { .lomax =  58500000, .svco = 3, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
+       { .lomax =  69250000, .svco = 0, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
+       { .lomax =  83625000, .svco = 1, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
+       { .lomax =  97500000, .svco = 2, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
+       { .lomax = 100250000, .svco = 2, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
+       { .lomax = 117000000, .svco = 3, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
+       { .lomax = 138500000, .svco = 0, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
+       { .lomax = 167250000, .svco = 1, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
+       { .lomax = 187000000, .svco = 2, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
+       { .lomax = 200500000, .svco = 2, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 1},
+       { .lomax = 234000000, .svco = 3, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 3},
+       { .lomax = 277000000, .svco = 0, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 3},
+       { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 1},
+       { .lomax = 334500000, .svco = 1, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
+       { .lomax = 401000000, .svco = 2, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
+       { .lomax = 468000000, .svco = 3, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 1},
+       { .lomax = 535000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
+       { .lomax = 554000000, .svco = 0, .spd = 0, .scr = 2, .sbs = 3, .gc3 = 1},
+       { .lomax = 638000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+       { .lomax = 669000000, .svco = 1, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
+       { .lomax = 720000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+       { .lomax = 802000000, .svco = 2, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
+       { .lomax = 835000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+       { .lomax = 885000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+       { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
+       { .lomax =         0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
+};
+
+static struct tda827xa_data tda827xa_analog[] = {
+       { .lomax =  56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3},
+       { .lomax =  67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
+       { .lomax =  81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
+       { .lomax =  97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
+       { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
+       { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
+       { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
+       { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
+       { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
+       { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
+       { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3},
+       { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3},
+       { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
+       { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
+       { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
+       { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
+       { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
+       { .lomax = 554000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
+       { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
+       { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
+       { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
+       { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
+       { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
+       { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
+       { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
+       { .lomax =         0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
+};
+
+static int tda827xa_sleep(struct dvb_frontend *fe)
+{
+       struct tda827x_priv *priv = fe->tuner_priv;
+       static u8 buf[] = { 0x30, 0x90 };
+       struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
+                              .buf = buf, .len = sizeof(buf) };
+
+       dprintk("%s:\n", __func__);
+
+       tuner_transfer(fe, &msg, 1);
+
+       if (priv->cfg && priv->cfg->sleep)
+               priv->cfg->sleep(fe);
+
+       return 0;
+}
+
+static void tda827xa_lna_gain(struct dvb_frontend *fe, int high,
+                             struct analog_parameters *params)
+{
+       struct tda827x_priv *priv = fe->tuner_priv;
+       unsigned char buf[] = {0x22, 0x01};
+       int arg;
+       int gp_func;
+       struct i2c_msg msg = { .flags = 0, .buf = buf, .len = sizeof(buf) };
+
+       if (NULL == priv->cfg) {
+               dprintk("tda827x_config not defined, cannot set LNA gain!\n");
+               return;
+       }
+       msg.addr = priv->cfg->switch_addr;
+       if (priv->cfg->config) {
+               if (high)
+                       dprintk("setting LNA to high gain\n");
+               else
+                       dprintk("setting LNA to low gain\n");
+       }
+       switch (priv->cfg->config) {
+       case 0: /* no LNA */
+               break;
+       case 1: /* switch is GPIO 0 of tda8290 */
+       case 2:
+               if (params == NULL) {
+                       gp_func = 0;
+                       arg  = 0;
+               } else {
+                       /* turn Vsync on */
+                       gp_func = 1;
+                       if (params->std & V4L2_STD_MN)
+                               arg = 1;
+                       else
+                               arg = 0;
+               }
+               if (fe->callback)
+                       fe->callback(priv->i2c_adap->algo_data,
+                                    DVB_FRONTEND_COMPONENT_TUNER,
+                                    gp_func, arg);
+               buf[1] = high ? 0 : 1;
+               if (priv->cfg->config == 2)
+                       buf[1] = high ? 1 : 0;
+               tuner_transfer(fe, &msg, 1);
+               break;
+       case 3: /* switch with GPIO of saa713x */
+               if (fe->callback)
+                       fe->callback(priv->i2c_adap->algo_data,
+                                    DVB_FRONTEND_COMPONENT_TUNER, 0, high);
+               break;
+       }
+}
+
+static int tda827xa_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       struct tda827x_priv *priv = fe->tuner_priv;
+       struct tda827xa_data *frequency_map = tda827xa_dvbt;
+       u8 buf[11];
+
+       struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
+                              .buf = buf, .len = sizeof(buf) };
+
+       int i, tuner_freq, if_freq, rc;
+       u32 N;
+
+       dprintk("%s:\n", __func__);
+
+       tda827xa_lna_gain(fe, 1, NULL);
+       msleep(20);
+
+       if (c->bandwidth_hz == 0) {
+               if_freq = 5000000;
+       } else if (c->bandwidth_hz <= 6000000) {
+               if_freq = 4000000;
+       } else if (c->bandwidth_hz <= 7000000) {
+               if_freq = 4500000;
+       } else {        /* 8 MHz */
+               if_freq = 5000000;
+       }
+       tuner_freq = c->frequency;
+
+       switch (c->delivery_system) {
+       case SYS_DVBC_ANNEX_A:
+       case SYS_DVBC_ANNEX_C:
+               dprintk("%s select tda827xa_dvbc\n", __func__);
+               frequency_map = tda827xa_dvbc;
+               break;
+       default:
+               break;
+       }
+
+       i = 0;
+       while (frequency_map[i].lomax < tuner_freq) {
+               if (frequency_map[i + 1].lomax == 0)
+                       break;
+               i++;
+       }
+
+       tuner_freq += if_freq;
+
+       N = ((tuner_freq + 31250) / 62500) << frequency_map[i].spd;
+       buf[0] = 0;            // subaddress
+       buf[1] = N >> 8;
+       buf[2] = N & 0xff;
+       buf[3] = 0;
+       buf[4] = 0x16;
+       buf[5] = (frequency_map[i].spd << 5) + (frequency_map[i].svco << 3) +
+                       frequency_map[i].sbs;
+       buf[6] = 0x4b + (frequency_map[i].gc3 << 4);
+       buf[7] = 0x1c;
+       buf[8] = 0x06;
+       buf[9] = 0x24;
+       buf[10] = 0x00;
+       msg.len = 11;
+       rc = tuner_transfer(fe, &msg, 1);
+       if (rc < 0)
+               goto err;
+
+       buf[0] = 0x90;
+       buf[1] = 0xff;
+       buf[2] = 0x60;
+       buf[3] = 0x00;
+       buf[4] = 0x59;  // lpsel, for 6MHz + 2
+       msg.len = 5;
+       rc = tuner_transfer(fe, &msg, 1);
+       if (rc < 0)
+               goto err;
+
+       buf[0] = 0xa0;
+       buf[1] = 0x40;
+       msg.len = 2;
+       rc = tuner_transfer(fe, &msg, 1);
+       if (rc < 0)
+               goto err;
+
+       msleep(11);
+       msg.flags = I2C_M_RD;
+       rc = tuner_transfer(fe, &msg, 1);
+       if (rc < 0)
+               goto err;
+       msg.flags = 0;
+
+       buf[1] >>= 4;
+       dprintk("tda8275a AGC2 gain is: %d\n", buf[1]);
+       if ((buf[1]) < 2) {
+               tda827xa_lna_gain(fe, 0, NULL);
+               buf[0] = 0x60;
+               buf[1] = 0x0c;
+               rc = tuner_transfer(fe, &msg, 1);
+               if (rc < 0)
+                       goto err;
+       }
+
+       buf[0] = 0xc0;
+       buf[1] = 0x99;    // lpsel, for 6MHz + 2
+       rc = tuner_transfer(fe, &msg, 1);
+       if (rc < 0)
+               goto err;
+
+       buf[0] = 0x60;
+       buf[1] = 0x3c;
+       rc = tuner_transfer(fe, &msg, 1);
+       if (rc < 0)
+               goto err;
+
+       /* correct CP value */
+       buf[0] = 0x30;
+       buf[1] = 0x10 + frequency_map[i].scr;
+       rc = tuner_transfer(fe, &msg, 1);
+       if (rc < 0)
+               goto err;
+
+       msleep(163);
+       buf[0] = 0xc0;
+       buf[1] = 0x39;  // lpsel, for 6MHz + 2
+       rc = tuner_transfer(fe, &msg, 1);
+       if (rc < 0)
+               goto err;
+
+       msleep(3);
+       /* freeze AGC1 */
+       buf[0] = 0x50;
+       buf[1] = 0x4f + (frequency_map[i].gc3 << 4);
+       rc = tuner_transfer(fe, &msg, 1);
+       if (rc < 0)
+               goto err;
+
+       priv->frequency = c->frequency;
+       priv->bandwidth = c->bandwidth_hz;
+
+       return 0;
+
+err:
+       printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
+              __func__, priv->i2c_addr << 1);
+       return rc;
+}
+
+
+static int tda827xa_set_analog_params(struct dvb_frontend *fe,
+                                     struct analog_parameters *params)
+{
+       unsigned char tuner_reg[11];
+       u32 N;
+       int i;
+       struct tda827x_priv *priv = fe->tuner_priv;
+       struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
+                              .buf = tuner_reg, .len = sizeof(tuner_reg) };
+       unsigned int freq = params->frequency;
+
+       tda827x_set_std(fe, params);
+
+       tda827xa_lna_gain(fe, 1, params);
+       msleep(10);
+
+       if (params->mode == V4L2_TUNER_RADIO)
+               freq = freq / 1000;
+
+       N = freq + priv->sgIF;
+
+       i = 0;
+       while (tda827xa_analog[i].lomax < N * 62500) {
+               if (tda827xa_analog[i + 1].lomax == 0)
+                       break;
+               i++;
+       }
+
+       N = N << tda827xa_analog[i].spd;
+
+       tuner_reg[0] = 0;
+       tuner_reg[1] = (unsigned char)(N>>8);
+       tuner_reg[2] = (unsigned char) N;
+       tuner_reg[3] = 0;
+       tuner_reg[4] = 0x16;
+       tuner_reg[5] = (tda827xa_analog[i].spd << 5) +
+                      (tda827xa_analog[i].svco << 3) +
+                       tda827xa_analog[i].sbs;
+       tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4);
+       tuner_reg[7] = 0x1c;
+       tuner_reg[8] = 4;
+       tuner_reg[9] = 0x20;
+       tuner_reg[10] = 0x00;
+       msg.len = 11;
+       tuner_transfer(fe, &msg, 1);
+
+       tuner_reg[0] = 0x90;
+       tuner_reg[1] = 0xff;
+       tuner_reg[2] = 0xe0;
+       tuner_reg[3] = 0;
+       tuner_reg[4] = 0x99 + (priv->lpsel << 1);
+       msg.len = 5;
+       tuner_transfer(fe, &msg, 1);
+
+       tuner_reg[0] = 0xa0;
+       tuner_reg[1] = 0xc0;
+       msg.len = 2;
+       tuner_transfer(fe, &msg, 1);
+
+       tuner_reg[0] = 0x30;
+       tuner_reg[1] = 0x10 + tda827xa_analog[i].scr;
+       tuner_transfer(fe, &msg, 1);
+
+       msg.flags = I2C_M_RD;
+       tuner_transfer(fe, &msg, 1);
+       msg.flags = 0;
+       tuner_reg[1] >>= 4;
+       dprintk("AGC2 gain is: %d\n", tuner_reg[1]);
+       if (tuner_reg[1] < 1)
+               tda827xa_lna_gain(fe, 0, params);
+
+       msleep(100);
+       tuner_reg[0] = 0x60;
+       tuner_reg[1] = 0x3c;
+       tuner_transfer(fe, &msg, 1);
+
+       msleep(163);
+       tuner_reg[0] = 0x50;
+       tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
+       tuner_transfer(fe, &msg, 1);
+
+       tuner_reg[0] = 0x80;
+       tuner_reg[1] = 0x28;
+       tuner_transfer(fe, &msg, 1);
+
+       tuner_reg[0] = 0xb0;
+       tuner_reg[1] = 0x01;
+       tuner_transfer(fe, &msg, 1);
+
+       tuner_reg[0] = 0xc0;
+       tuner_reg[1] = 0x19 + (priv->lpsel << 1);
+       tuner_transfer(fe, &msg, 1);
+
+       priv->frequency = params->frequency;
+
+       return 0;
+}
+
+static void tda827xa_agcf(struct dvb_frontend *fe)
+{
+       struct tda827x_priv *priv = fe->tuner_priv;
+       unsigned char data[] = {0x80, 0x2c};
+       struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0,
+                             .buf = data, .len = 2};
+       tuner_transfer(fe, &msg, 1);
+}
+
+/* ------------------------------------------------------------------ */
+
+static int tda827x_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static int tda827x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct tda827x_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static int tda827x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct tda827x_priv *priv = fe->tuner_priv;
+       *bandwidth = priv->bandwidth;
+       return 0;
+}
+
+static int tda827x_init(struct dvb_frontend *fe)
+{
+       struct tda827x_priv *priv = fe->tuner_priv;
+       dprintk("%s:\n", __func__);
+       if (priv->cfg && priv->cfg->init)
+               priv->cfg->init(fe);
+
+       return 0;
+}
+
+static int tda827x_probe_version(struct dvb_frontend *fe);
+
+static int tda827x_initial_init(struct dvb_frontend *fe)
+{
+       int ret;
+       ret = tda827x_probe_version(fe);
+       if (ret)
+               return ret;
+       return fe->ops.tuner_ops.init(fe);
+}
+
+static int tda827x_initial_sleep(struct dvb_frontend *fe)
+{
+       int ret;
+       ret = tda827x_probe_version(fe);
+       if (ret)
+               return ret;
+       return fe->ops.tuner_ops.sleep(fe);
+}
+
+static struct dvb_tuner_ops tda827xo_tuner_ops = {
+       .info = {
+               .name = "Philips TDA827X",
+               .frequency_min  =  55000000,
+               .frequency_max  = 860000000,
+               .frequency_step =    250000
+       },
+       .release = tda827x_release,
+       .init = tda827x_initial_init,
+       .sleep = tda827x_initial_sleep,
+       .set_params = tda827xo_set_params,
+       .set_analog_params = tda827xo_set_analog_params,
+       .get_frequency = tda827x_get_frequency,
+       .get_bandwidth = tda827x_get_bandwidth,
+};
+
+static struct dvb_tuner_ops tda827xa_tuner_ops = {
+       .info = {
+               .name = "Philips TDA827XA",
+               .frequency_min  =  44000000,
+               .frequency_max  = 906000000,
+               .frequency_step =     62500
+       },
+       .release = tda827x_release,
+       .init = tda827x_init,
+       .sleep = tda827xa_sleep,
+       .set_params = tda827xa_set_params,
+       .set_analog_params = tda827xa_set_analog_params,
+       .get_frequency = tda827x_get_frequency,
+       .get_bandwidth = tda827x_get_bandwidth,
+};
+
+static int tda827x_probe_version(struct dvb_frontend *fe)
+{
+       u8 data;
+       int rc;
+       struct tda827x_priv *priv = fe->tuner_priv;
+       struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD,
+                              .buf = &data, .len = 1 };
+
+       rc = tuner_transfer(fe, &msg, 1);
+
+       if (rc < 0) {
+               printk("%s: could not read from tuner at addr: 0x%02x\n",
+                      __func__, msg.addr << 1);
+               return rc;
+       }
+       if ((data & 0x3c) == 0) {
+               dprintk("tda827x tuner found\n");
+               fe->ops.tuner_ops.init  = tda827x_init;
+               fe->ops.tuner_ops.sleep = tda827xo_sleep;
+               if (priv->cfg)
+                       priv->cfg->agcf = tda827xo_agcf;
+       } else {
+               dprintk("tda827xa tuner found\n");
+               memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops));
+               if (priv->cfg)
+                       priv->cfg->agcf = tda827xa_agcf;
+       }
+       return 0;
+}
+
+struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr,
+                                   struct i2c_adapter *i2c,
+                                   struct tda827x_config *cfg)
+{
+       struct tda827x_priv *priv = NULL;
+
+       dprintk("%s:\n", __func__);
+       priv = kzalloc(sizeof(struct tda827x_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->i2c_addr = addr;
+       priv->i2c_adap = i2c;
+       priv->cfg = cfg;
+       memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops));
+       fe->tuner_priv = priv;
+
+       dprintk("type set to %s\n", fe->ops.tuner_ops.info.name);
+
+       return fe;
+}
+EXPORT_SYMBOL_GPL(tda827x_attach);
+
+MODULE_DESCRIPTION("DVB TDA827x driver");
+MODULE_AUTHOR("Hartmut Hackmann <hartmut.hackmann@t-online.de>");
+MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
+MODULE_LICENSE("GPL");
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/tuners/tda827x.h b/drivers/media/tuners/tda827x.h
new file mode 100644 (file)
index 0000000..7d72ce0
--- /dev/null
@@ -0,0 +1,68 @@
+  /*
+     DVB Driver for Philips tda827x / tda827xa Silicon tuners
+
+     (c) 2005 Hartmut Hackmann
+     (c) 2007 Michael Krufky
+
+     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 __DVB_TDA827X_H__
+#define __DVB_TDA827X_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+struct tda827x_config
+{
+       /* saa7134 - provided callbacks */
+       int (*init) (struct dvb_frontend *fe);
+       int (*sleep) (struct dvb_frontend *fe);
+
+       /* interface to tda829x driver */
+       unsigned int config;
+       int          switch_addr;
+
+       void (*agcf)(struct dvb_frontend *fe);
+};
+
+
+/**
+ * Attach a tda827x tuner to the supplied frontend structure.
+ *
+ * @param fe Frontend to attach to.
+ * @param addr i2c address of the tuner.
+ * @param i2c i2c adapter to use.
+ * @param cfg optional callback function pointers.
+ * @return FE pointer on success, NULL on failure.
+ */
+#if defined(CONFIG_MEDIA_TUNER_TDA827X) || (defined(CONFIG_MEDIA_TUNER_TDA827X_MODULE) && defined(MODULE))
+extern struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe, int addr,
+                                          struct i2c_adapter *i2c,
+                                          struct tda827x_config *cfg);
+#else
+static inline struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe,
+                                                 int addr,
+                                                 struct i2c_adapter *i2c,
+                                                 struct tda827x_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_MEDIA_TUNER_TDA827X
+
+#endif // __DVB_TDA827X_H__
diff --git a/drivers/media/tuners/tda8290.c b/drivers/media/tuners/tda8290.c
new file mode 100644 (file)
index 0000000..8c48521
--- /dev/null
@@ -0,0 +1,874 @@
+/*
+
+   i2c tv tuner chip device driver
+   controls the philips tda8290+75 tuner chip combo.
+
+   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.
+
+   This "tda8290" module was split apart from the original "tuner" module.
+*/
+
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include "tuner-i2c.h"
+#include "tda8290.h"
+#include "tda827x.h"
+#include "tda18271.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable verbose debug messages");
+
+static int deemphasis_50;
+module_param(deemphasis_50, int, 0644);
+MODULE_PARM_DESC(deemphasis_50, "0 - 75us deemphasis; 1 - 50us deemphasis");
+
+/* ---------------------------------------------------------------------- */
+
+struct tda8290_priv {
+       struct tuner_i2c_props i2c_props;
+
+       unsigned char tda8290_easy_mode;
+
+       unsigned char tda827x_addr;
+
+       unsigned char ver;
+#define TDA8290   1
+#define TDA8295   2
+#define TDA8275   4
+#define TDA8275A  8
+#define TDA18271 16
+
+       struct tda827x_config cfg;
+};
+
+/*---------------------------------------------------------------------*/
+
+static int tda8290_i2c_bridge(struct dvb_frontend *fe, int close)
+{
+       struct tda8290_priv *priv = fe->analog_demod_priv;
+
+       unsigned char  enable[2] = { 0x21, 0xC0 };
+       unsigned char disable[2] = { 0x21, 0x00 };
+       unsigned char *msg;
+
+       if (close) {
+               msg = enable;
+               tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
+               /* let the bridge stabilize */
+               msleep(20);
+       } else {
+               msg = disable;
+               tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
+       }
+
+       return 0;
+}
+
+static int tda8295_i2c_bridge(struct dvb_frontend *fe, int close)
+{
+       struct tda8290_priv *priv = fe->analog_demod_priv;
+
+       unsigned char  enable[2] = { 0x45, 0xc1 };
+       unsigned char disable[2] = { 0x46, 0x00 };
+       unsigned char buf[3] = { 0x45, 0x01, 0x00 };
+       unsigned char *msg;
+
+       if (close) {
+               msg = enable;
+               tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
+               /* let the bridge stabilize */
+               msleep(20);
+       } else {
+               msg = disable;
+               tuner_i2c_xfer_send_recv(&priv->i2c_props, msg, 1, &msg[1], 1);
+
+               buf[2] = msg[1];
+               buf[2] &= ~0x04;
+               tuner_i2c_xfer_send(&priv->i2c_props, buf, 3);
+               msleep(5);
+
+               msg[1] |= 0x04;
+               tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
+       }
+
+       return 0;
+}
+
+/*---------------------------------------------------------------------*/
+
+static void set_audio(struct dvb_frontend *fe,
+                     struct analog_parameters *params)
+{
+       struct tda8290_priv *priv = fe->analog_demod_priv;
+       char* mode;
+
+       if (params->std & V4L2_STD_MN) {
+               priv->tda8290_easy_mode = 0x01;
+               mode = "MN";
+       } else if (params->std & V4L2_STD_B) {
+               priv->tda8290_easy_mode = 0x02;
+               mode = "B";
+       } else if (params->std & V4L2_STD_GH) {
+               priv->tda8290_easy_mode = 0x04;
+               mode = "GH";
+       } else if (params->std & V4L2_STD_PAL_I) {
+               priv->tda8290_easy_mode = 0x08;
+               mode = "I";
+       } else if (params->std & V4L2_STD_DK) {
+               priv->tda8290_easy_mode = 0x10;
+               mode = "DK";
+       } else if (params->std & V4L2_STD_SECAM_L) {
+               priv->tda8290_easy_mode = 0x20;
+               mode = "L";
+       } else if (params->std & V4L2_STD_SECAM_LC) {
+               priv->tda8290_easy_mode = 0x40;
+               mode = "LC";
+       } else {
+               priv->tda8290_easy_mode = 0x10;
+               mode = "xx";
+       }
+
+       if (params->mode == V4L2_TUNER_RADIO) {
+               /* Set TDA8295 to FM radio; Start TDA8290 with MN values */
+               priv->tda8290_easy_mode = (priv->ver & TDA8295) ? 0x80 : 0x01;
+               tuner_dbg("setting to radio FM\n");
+       } else {
+               tuner_dbg("setting tda829x to system %s\n", mode);
+       }
+}
+
+static struct {
+       unsigned char seq[2];
+} fm_mode[] = {
+       { { 0x01, 0x81} },      /* Put device into expert mode */
+       { { 0x03, 0x48} },      /* Disable NOTCH and VIDEO filters */
+       { { 0x04, 0x04} },      /* Disable color carrier filter (SSIF) */
+       { { 0x05, 0x04} },      /* ADC headroom */
+       { { 0x06, 0x10} },      /* group delay flat */
+
+       { { 0x07, 0x00} },      /* use the same radio DTO values as a tda8295 */
+       { { 0x08, 0x00} },
+       { { 0x09, 0x80} },
+       { { 0x0a, 0xda} },
+       { { 0x0b, 0x4b} },
+       { { 0x0c, 0x68} },
+
+       { { 0x0d, 0x00} },      /* PLL off, no video carrier detect */
+       { { 0x14, 0x00} },      /* disable auto mute if no video */
+};
+
+static void tda8290_set_params(struct dvb_frontend *fe,
+                              struct analog_parameters *params)
+{
+       struct tda8290_priv *priv = fe->analog_demod_priv;
+
+       unsigned char soft_reset[]  = { 0x00, 0x00 };
+       unsigned char easy_mode[]   = { 0x01, priv->tda8290_easy_mode };
+       unsigned char expert_mode[] = { 0x01, 0x80 };
+       unsigned char agc_out_on[]  = { 0x02, 0x00 };
+       unsigned char gainset_off[] = { 0x28, 0x14 };
+       unsigned char if_agc_spd[]  = { 0x0f, 0x88 };
+       unsigned char adc_head_6[]  = { 0x05, 0x04 };
+       unsigned char adc_head_9[]  = { 0x05, 0x02 };
+       unsigned char adc_head_12[] = { 0x05, 0x01 };
+       unsigned char pll_bw_nom[]  = { 0x0d, 0x47 };
+       unsigned char pll_bw_low[]  = { 0x0d, 0x27 };
+       unsigned char gainset_2[]   = { 0x28, 0x64 };
+       unsigned char agc_rst_on[]  = { 0x0e, 0x0b };
+       unsigned char agc_rst_off[] = { 0x0e, 0x09 };
+       unsigned char if_agc_set[]  = { 0x0f, 0x81 };
+       unsigned char addr_adc_sat  = 0x1a;
+       unsigned char addr_agc_stat = 0x1d;
+       unsigned char addr_pll_stat = 0x1b;
+       unsigned char adc_sat, agc_stat,
+                     pll_stat;
+       int i;
+
+       set_audio(fe, params);
+
+       if (priv->cfg.config)
+               tuner_dbg("tda827xa config is 0x%02x\n", priv->cfg.config);
+       tuner_i2c_xfer_send(&priv->i2c_props, easy_mode, 2);
+       tuner_i2c_xfer_send(&priv->i2c_props, agc_out_on, 2);
+       tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2);
+       msleep(1);
+
+       if (params->mode == V4L2_TUNER_RADIO) {
+               unsigned char deemphasis[]  = { 0x13, 1 };
+
+               /* FIXME: allow using a different deemphasis */
+
+               if (deemphasis_50)
+                       deemphasis[1] = 2;
+
+               for (i = 0; i < ARRAY_SIZE(fm_mode); i++)
+                       tuner_i2c_xfer_send(&priv->i2c_props, fm_mode[i].seq, 2);
+
+               tuner_i2c_xfer_send(&priv->i2c_props, deemphasis, 2);
+       } else {
+               expert_mode[1] = priv->tda8290_easy_mode + 0x80;
+               tuner_i2c_xfer_send(&priv->i2c_props, expert_mode, 2);
+               tuner_i2c_xfer_send(&priv->i2c_props, gainset_off, 2);
+               tuner_i2c_xfer_send(&priv->i2c_props, if_agc_spd, 2);
+               if (priv->tda8290_easy_mode & 0x60)
+                       tuner_i2c_xfer_send(&priv->i2c_props, adc_head_9, 2);
+               else
+                       tuner_i2c_xfer_send(&priv->i2c_props, adc_head_6, 2);
+               tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2);
+       }
+
+
+       tda8290_i2c_bridge(fe, 1);
+
+       if (fe->ops.tuner_ops.set_analog_params)
+               fe->ops.tuner_ops.set_analog_params(fe, params);
+
+       for (i = 0; i < 3; i++) {
+               tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                        &addr_pll_stat, 1, &pll_stat, 1);
+               if (pll_stat & 0x80) {
+                       tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                                &addr_adc_sat, 1,
+                                                &adc_sat, 1);
+                       tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                                &addr_agc_stat, 1,
+                                                &agc_stat, 1);
+                       tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat);
+                       break;
+               } else {
+                       tuner_dbg("tda8290 not locked, no signal?\n");
+                       msleep(100);
+               }
+       }
+       /* adjust headroom resp. gain */
+       if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) {
+               tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n",
+                          agc_stat, adc_sat, pll_stat & 0x80);
+               tuner_i2c_xfer_send(&priv->i2c_props, gainset_2, 2);
+               msleep(100);
+               tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                        &addr_agc_stat, 1, &agc_stat, 1);
+               tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                        &addr_pll_stat, 1, &pll_stat, 1);
+               if ((agc_stat > 115) || !(pll_stat & 0x80)) {
+                       tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n",
+                                  agc_stat, pll_stat & 0x80);
+                       if (priv->cfg.agcf)
+                               priv->cfg.agcf(fe);
+                       msleep(100);
+                       tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                                &addr_agc_stat, 1,
+                                                &agc_stat, 1);
+                       tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                                &addr_pll_stat, 1,
+                                                &pll_stat, 1);
+                       if((agc_stat > 115) || !(pll_stat & 0x80)) {
+                               tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat);
+                               tuner_i2c_xfer_send(&priv->i2c_props, adc_head_12, 2);
+                               tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_low, 2);
+                               msleep(100);
+                       }
+               }
+       }
+
+       /* l/ l' deadlock? */
+       if(priv->tda8290_easy_mode & 0x60) {
+               tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                        &addr_adc_sat, 1,
+                                        &adc_sat, 1);
+               tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                        &addr_pll_stat, 1,
+                                        &pll_stat, 1);
+               if ((adc_sat > 20) || !(pll_stat & 0x80)) {
+                       tuner_dbg("trying to resolve SECAM L deadlock\n");
+                       tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_on, 2);
+                       msleep(40);
+                       tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_off, 2);
+               }
+       }
+
+       tda8290_i2c_bridge(fe, 0);
+       tuner_i2c_xfer_send(&priv->i2c_props, if_agc_set, 2);
+}
+
+/*---------------------------------------------------------------------*/
+
+static void tda8295_power(struct dvb_frontend *fe, int enable)
+{
+       struct tda8290_priv *priv = fe->analog_demod_priv;
+       unsigned char buf[] = { 0x30, 0x00 }; /* clb_stdbt */
+
+       tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1);
+
+       if (enable)
+               buf[1] = 0x01;
+       else
+               buf[1] = 0x03;
+
+       tuner_i2c_xfer_send(&priv->i2c_props, buf, 2);
+}
+
+static void tda8295_set_easy_mode(struct dvb_frontend *fe, int enable)
+{
+       struct tda8290_priv *priv = fe->analog_demod_priv;
+       unsigned char buf[] = { 0x01, 0x00 };
+
+       tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1);
+
+       if (enable)
+               buf[1] = 0x01; /* rising edge sets regs 0x02 - 0x23 */
+       else
+               buf[1] = 0x00; /* reset active bit */
+
+       tuner_i2c_xfer_send(&priv->i2c_props, buf, 2);
+}
+
+static void tda8295_set_video_std(struct dvb_frontend *fe)
+{
+       struct tda8290_priv *priv = fe->analog_demod_priv;
+       unsigned char buf[] = { 0x00, priv->tda8290_easy_mode };
+
+       tuner_i2c_xfer_send(&priv->i2c_props, buf, 2);
+
+       tda8295_set_easy_mode(fe, 1);
+       msleep(20);
+       tda8295_set_easy_mode(fe, 0);
+}
+
+/*---------------------------------------------------------------------*/
+
+static void tda8295_agc1_out(struct dvb_frontend *fe, int enable)
+{
+       struct tda8290_priv *priv = fe->analog_demod_priv;
+       unsigned char buf[] = { 0x02, 0x00 }; /* DIV_FUNC */
+
+       tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1);
+
+       if (enable)
+               buf[1] &= ~0x40;
+       else
+               buf[1] |= 0x40;
+
+       tuner_i2c_xfer_send(&priv->i2c_props, buf, 2);
+}
+
+static void tda8295_agc2_out(struct dvb_frontend *fe, int enable)
+{
+       struct tda8290_priv *priv = fe->analog_demod_priv;
+       unsigned char set_gpio_cf[]    = { 0x44, 0x00 };
+       unsigned char set_gpio_val[]   = { 0x46, 0x00 };
+
+       tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                &set_gpio_cf[0], 1, &set_gpio_cf[1], 1);
+       tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                &set_gpio_val[0], 1, &set_gpio_val[1], 1);
+
+       set_gpio_cf[1] &= 0xf0; /* clear GPIO_0 bits 3-0 */
+
+       if (enable) {
+               set_gpio_cf[1]  |= 0x01; /* config GPIO_0 as Open Drain Out */
+               set_gpio_val[1] &= 0xfe; /* set GPIO_0 pin low */
+       }
+       tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_cf, 2);
+       tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_val, 2);
+}
+
+static int tda8295_has_signal(struct dvb_frontend *fe)
+{
+       struct tda8290_priv *priv = fe->analog_demod_priv;
+
+       unsigned char hvpll_stat = 0x26;
+       unsigned char ret;
+
+       tuner_i2c_xfer_send_recv(&priv->i2c_props, &hvpll_stat, 1, &ret, 1);
+       return (ret & 0x01) ? 65535 : 0;
+}
+
+/*---------------------------------------------------------------------*/
+
+static void tda8295_set_params(struct dvb_frontend *fe,
+                              struct analog_parameters *params)
+{
+       struct tda8290_priv *priv = fe->analog_demod_priv;
+
+       unsigned char blanking_mode[]     = { 0x1d, 0x00 };
+
+       set_audio(fe, params);
+
+       tuner_dbg("%s: freq = %d\n", __func__, params->frequency);
+
+       tda8295_power(fe, 1);
+       tda8295_agc1_out(fe, 1);
+
+       tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                &blanking_mode[0], 1, &blanking_mode[1], 1);
+
+       tda8295_set_video_std(fe);
+
+       blanking_mode[1] = 0x03;
+       tuner_i2c_xfer_send(&priv->i2c_props, blanking_mode, 2);
+       msleep(20);
+
+       tda8295_i2c_bridge(fe, 1);
+
+       if (fe->ops.tuner_ops.set_analog_params)
+               fe->ops.tuner_ops.set_analog_params(fe, params);
+
+       if (priv->cfg.agcf)
+               priv->cfg.agcf(fe);
+
+       if (tda8295_has_signal(fe))
+               tuner_dbg("tda8295 is locked\n");
+       else
+               tuner_dbg("tda8295 not locked, no signal?\n");
+
+       tda8295_i2c_bridge(fe, 0);
+}
+
+/*---------------------------------------------------------------------*/
+
+static int tda8290_has_signal(struct dvb_frontend *fe)
+{
+       struct tda8290_priv *priv = fe->analog_demod_priv;
+
+       unsigned char i2c_get_afc[1] = { 0x1B };
+       unsigned char afc = 0;
+
+       tuner_i2c_xfer_send_recv(&priv->i2c_props,
+                                i2c_get_afc, ARRAY_SIZE(i2c_get_afc), &afc, 1);
+       return (afc & 0x80)? 65535:0;
+}
+
+/*---------------------------------------------------------------------*/
+
+static void tda8290_standby(struct dvb_frontend *fe)
+{
+       struct tda8290_priv *priv = fe->analog_demod_priv;
+
+       unsigned char cb1[] = { 0x30, 0xD0 };
+       unsigned char tda8290_standby[] = { 0x00, 0x02 };
+       unsigned char tda8290_agc_tri[] = { 0x02, 0x20 };
+       struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, .buf=cb1, .len = 2};
+
+       tda8290_i2c_bridge(fe, 1);
+       if (priv->ver & TDA8275A)
+               cb1[1] = 0x90;
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
+       tda8290_i2c_bridge(fe, 0);
+       tuner_i2c_xfer_send(&priv->i2c_props, tda8290_agc_tri, 2);
+       tuner_i2c_xfer_send(&priv->i2c_props, tda8290_standby, 2);
+}
+
+static void tda8295_standby(struct dvb_frontend *fe)
+{
+       tda8295_agc1_out(fe, 0); /* Put AGC in tri-state */
+
+       tda8295_power(fe, 0);
+}
+
+static void tda8290_init_if(struct dvb_frontend *fe)
+{
+       struct tda8290_priv *priv = fe->analog_demod_priv;
+
+       unsigned char set_VS[] = { 0x30, 0x6F };
+       unsigned char set_GP00_CF[] = { 0x20, 0x01 };
+       unsigned char set_GP01_CF[] = { 0x20, 0x0B };
+
+       if ((priv->cfg.config == 1) || (priv->cfg.config == 2))
+               tuner_i2c_xfer_send(&priv->i2c_props, set_GP00_CF, 2);
+       else
+               tuner_i2c_xfer_send(&priv->i2c_props, set_GP01_CF, 2);
+       tuner_i2c_xfer_send(&priv->i2c_props, set_VS, 2);
+}
+
+static void tda8295_init_if(struct dvb_frontend *fe)
+{
+       struct tda8290_priv *priv = fe->analog_demod_priv;
+
+       static unsigned char set_adc_ctl[]       = { 0x33, 0x14 };
+       static unsigned char set_adc_ctl2[]      = { 0x34, 0x00 };
+       static unsigned char set_pll_reg6[]      = { 0x3e, 0x63 };
+       static unsigned char set_pll_reg0[]      = { 0x38, 0x23 };
+       static unsigned char set_pll_reg7[]      = { 0x3f, 0x01 };
+       static unsigned char set_pll_reg10[]     = { 0x42, 0x61 };
+       static unsigned char set_gpio_reg0[]     = { 0x44, 0x0b };
+
+       tda8295_power(fe, 1);
+
+       tda8295_set_easy_mode(fe, 0);
+       tda8295_set_video_std(fe);
+
+       tuner_i2c_xfer_send(&priv->i2c_props, set_adc_ctl, 2);
+       tuner_i2c_xfer_send(&priv->i2c_props, set_adc_ctl2, 2);
+       tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg6, 2);
+       tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg0, 2);
+       tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg7, 2);
+       tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg10, 2);
+       tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_reg0, 2);
+
+       tda8295_agc1_out(fe, 0);
+       tda8295_agc2_out(fe, 0);
+}
+
+static void tda8290_init_tuner(struct dvb_frontend *fe)
+{
+       struct tda8290_priv *priv = fe->analog_demod_priv;
+       unsigned char tda8275_init[]  = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf,
+                                         0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 };
+       unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b,
+                                         0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b };
+       struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0,
+                             .buf=tda8275_init, .len = 14};
+       if (priv->ver & TDA8275A)
+               msg.buf = tda8275a_init;
+
+       tda8290_i2c_bridge(fe, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
+       tda8290_i2c_bridge(fe, 0);
+}
+
+/*---------------------------------------------------------------------*/
+
+static void tda829x_release(struct dvb_frontend *fe)
+{
+       struct tda8290_priv *priv = fe->analog_demod_priv;
+
+       /* only try to release the tuner if we've
+        * attached it from within this module */
+       if (priv->ver & (TDA18271 | TDA8275 | TDA8275A))
+               if (fe->ops.tuner_ops.release)
+                       fe->ops.tuner_ops.release(fe);
+
+       kfree(fe->analog_demod_priv);
+       fe->analog_demod_priv = NULL;
+}
+
+static struct tda18271_config tda829x_tda18271_config = {
+       .gate    = TDA18271_GATE_ANALOG,
+};
+
+static int tda829x_find_tuner(struct dvb_frontend *fe)
+{
+       struct tda8290_priv *priv = fe->analog_demod_priv;
+       struct analog_demod_ops *analog_ops = &fe->ops.analog_ops;
+       int i, ret, tuners_found;
+       u32 tuner_addrs;
+       u8 data;
+       struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 };
+
+       if (!analog_ops->i2c_gate_ctrl) {
+               printk(KERN_ERR "tda8290: no gate control were provided!\n");
+
+               return -EINVAL;
+       }
+
+       analog_ops->i2c_gate_ctrl(fe, 1);
+
+       /* probe for tuner chip */
+       tuners_found = 0;
+       tuner_addrs = 0;
+       for (i = 0x60; i <= 0x63; i++) {
+               msg.addr = i;
+               ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
+               if (ret == 1) {
+                       tuners_found++;
+                       tuner_addrs = (tuner_addrs << 8) + i;
+               }
+       }
+       /* if there is more than one tuner, we expect the right one is
+          behind the bridge and we choose the highest address that doesn't
+          give a response now
+        */
+
+       analog_ops->i2c_gate_ctrl(fe, 0);
+
+       if (tuners_found > 1)
+               for (i = 0; i < tuners_found; i++) {
+                       msg.addr = tuner_addrs  & 0xff;
+                       ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
+                       if (ret == 1)
+                               tuner_addrs = tuner_addrs >> 8;
+                       else
+                               break;
+               }
+
+       if (tuner_addrs == 0) {
+               tuner_addrs = 0x60;
+               tuner_info("could not clearly identify tuner address, "
+                          "defaulting to %x\n", tuner_addrs);
+       } else {
+               tuner_addrs = tuner_addrs & 0xff;
+               tuner_info("setting tuner address to %x\n", tuner_addrs);
+       }
+       priv->tda827x_addr = tuner_addrs;
+       msg.addr = tuner_addrs;
+
+       analog_ops->i2c_gate_ctrl(fe, 1);
+       ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
+
+       if (ret != 1) {
+               tuner_warn("tuner access failed!\n");
+               analog_ops->i2c_gate_ctrl(fe, 0);
+               return -EREMOTEIO;
+       }
+
+       if ((data == 0x83) || (data == 0x84)) {
+               priv->ver |= TDA18271;
+               tda829x_tda18271_config.config = priv->cfg.config;
+               dvb_attach(tda18271_attach, fe, priv->tda827x_addr,
+                          priv->i2c_props.adap, &tda829x_tda18271_config);
+       } else {
+               if ((data & 0x3c) == 0)
+                       priv->ver |= TDA8275;
+               else
+                       priv->ver |= TDA8275A;
+
+               dvb_attach(tda827x_attach, fe, priv->tda827x_addr,
+                          priv->i2c_props.adap, &priv->cfg);
+               priv->cfg.switch_addr = priv->i2c_props.addr;
+       }
+       if (fe->ops.tuner_ops.init)
+               fe->ops.tuner_ops.init(fe);
+
+       if (fe->ops.tuner_ops.sleep)
+               fe->ops.tuner_ops.sleep(fe);
+
+       analog_ops->i2c_gate_ctrl(fe, 0);
+
+       return 0;
+}
+
+static int tda8290_probe(struct tuner_i2c_props *i2c_props)
+{
+#define TDA8290_ID 0x89
+       u8 reg = 0x1f, id;
+       struct i2c_msg msg_read[] = {
+               { .addr = i2c_props->addr, .flags = 0, .len = 1, .buf = &reg },
+               { .addr = i2c_props->addr, .flags = I2C_M_RD, .len = 1, .buf = &id },
+       };
+
+       /* detect tda8290 */
+       if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) {
+               printk(KERN_WARNING "%s: couldn't read register 0x%02x\n",
+                              __func__, reg);
+               return -ENODEV;
+       }
+
+       if (id == TDA8290_ID) {
+               if (debug)
+                       printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n",
+                              __func__, i2c_adapter_id(i2c_props->adap),
+                              i2c_props->addr);
+               return 0;
+       }
+       return -ENODEV;
+}
+
+static int tda8295_probe(struct tuner_i2c_props *i2c_props)
+{
+#define TDA8295_ID 0x8a
+#define TDA8295C2_ID 0x8b
+       u8 reg = 0x2f, id;
+       struct i2c_msg msg_read[] = {
+               { .addr = i2c_props->addr, .flags = 0, .len = 1, .buf = &reg },
+               { .addr = i2c_props->addr, .flags = I2C_M_RD, .len = 1, .buf = &id },
+       };
+
+       /* detect tda8295 */
+       if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) {
+               printk(KERN_WARNING "%s: couldn't read register 0x%02x\n",
+                              __func__, reg);
+               return -ENODEV;
+       }
+
+       if ((id & 0xfe) == TDA8295_ID) {
+               if (debug)
+                       printk(KERN_DEBUG "%s: %s detected @ %d-%04x\n",
+                              __func__, (id == TDA8295_ID) ?
+                              "tda8295c1" : "tda8295c2",
+                              i2c_adapter_id(i2c_props->adap),
+                              i2c_props->addr);
+               return 0;
+       }
+
+       return -ENODEV;
+}
+
+static struct analog_demod_ops tda8290_ops = {
+       .set_params     = tda8290_set_params,
+       .has_signal     = tda8290_has_signal,
+       .standby        = tda8290_standby,
+       .release        = tda829x_release,
+       .i2c_gate_ctrl  = tda8290_i2c_bridge,
+};
+
+static struct analog_demod_ops tda8295_ops = {
+       .set_params     = tda8295_set_params,
+       .has_signal     = tda8295_has_signal,
+       .standby        = tda8295_standby,
+       .release        = tda829x_release,
+       .i2c_gate_ctrl  = tda8295_i2c_bridge,
+};
+
+struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
+                                   struct i2c_adapter *i2c_adap, u8 i2c_addr,
+                                   struct tda829x_config *cfg)
+{
+       struct tda8290_priv *priv = NULL;
+       char *name;
+
+       priv = kzalloc(sizeof(struct tda8290_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+       fe->analog_demod_priv = priv;
+
+       priv->i2c_props.addr     = i2c_addr;
+       priv->i2c_props.adap     = i2c_adap;
+       priv->i2c_props.name     = "tda829x";
+       if (cfg)
+               priv->cfg.config         = cfg->lna_cfg;
+
+       if (tda8290_probe(&priv->i2c_props) == 0) {
+               priv->ver = TDA8290;
+               memcpy(&fe->ops.analog_ops, &tda8290_ops,
+                      sizeof(struct analog_demod_ops));
+       }
+
+       if (tda8295_probe(&priv->i2c_props) == 0) {
+               priv->ver = TDA8295;
+               memcpy(&fe->ops.analog_ops, &tda8295_ops,
+                      sizeof(struct analog_demod_ops));
+       }
+
+       if (!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) {
+               tda8295_power(fe, 1);
+               if (tda829x_find_tuner(fe) < 0)
+                       goto fail;
+       }
+
+       switch (priv->ver) {
+       case TDA8290:
+               name = "tda8290";
+               break;
+       case TDA8295:
+               name = "tda8295";
+               break;
+       case TDA8290 | TDA8275:
+               name = "tda8290+75";
+               break;
+       case TDA8295 | TDA8275:
+               name = "tda8295+75";
+               break;
+       case TDA8290 | TDA8275A:
+               name = "tda8290+75a";
+               break;
+       case TDA8295 | TDA8275A:
+               name = "tda8295+75a";
+               break;
+       case TDA8290 | TDA18271:
+               name = "tda8290+18271";
+               break;
+       case TDA8295 | TDA18271:
+               name = "tda8295+18271";
+               break;
+       default:
+               goto fail;
+       }
+       tuner_info("type set to %s\n", name);
+
+       fe->ops.analog_ops.info.name = name;
+
+       if (priv->ver & TDA8290) {
+               if (priv->ver & (TDA8275 | TDA8275A))
+                       tda8290_init_tuner(fe);
+               tda8290_init_if(fe);
+       } else if (priv->ver & TDA8295)
+               tda8295_init_if(fe);
+
+       return fe;
+
+fail:
+       memset(&fe->ops.analog_ops, 0, sizeof(struct analog_demod_ops));
+
+       tda829x_release(fe);
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(tda829x_attach);
+
+int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr)
+{
+       struct tuner_i2c_props i2c_props = {
+               .adap = i2c_adap,
+               .addr = i2c_addr,
+       };
+
+       unsigned char soft_reset[]   = { 0x00, 0x00 };
+       unsigned char easy_mode_b[]  = { 0x01, 0x02 };
+       unsigned char easy_mode_g[]  = { 0x01, 0x04 };
+       unsigned char restore_9886[] = { 0x00, 0xd6, 0x30 };
+       unsigned char addr_dto_lsb = 0x07;
+       unsigned char data;
+#define PROBE_BUFFER_SIZE 8
+       unsigned char buf[PROBE_BUFFER_SIZE];
+       int i;
+
+       /* rule out tda9887, which would return the same byte repeatedly */
+       tuner_i2c_xfer_send_recv(&i2c_props,
+                                soft_reset, 1, buf, PROBE_BUFFER_SIZE);
+       for (i = 1; i < PROBE_BUFFER_SIZE; i++) {
+               if (buf[i] != buf[0])
+                       break;
+       }
+
+       /* all bytes are equal, not a tda829x - probably a tda9887 */
+       if (i == PROBE_BUFFER_SIZE)
+               return -ENODEV;
+
+       if ((tda8290_probe(&i2c_props) == 0) ||
+           (tda8295_probe(&i2c_props) == 0))
+               return 0;
+
+       /* fall back to old probing method */
+       tuner_i2c_xfer_send(&i2c_props, easy_mode_b, 2);
+       tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
+       tuner_i2c_xfer_send_recv(&i2c_props, &addr_dto_lsb, 1, &data, 1);
+       if (data == 0) {
+               tuner_i2c_xfer_send(&i2c_props, easy_mode_g, 2);
+               tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
+               tuner_i2c_xfer_send_recv(&i2c_props,
+                                        &addr_dto_lsb, 1, &data, 1);
+               if (data == 0x7b) {
+                       return 0;
+               }
+       }
+       tuner_i2c_xfer_send(&i2c_props, restore_9886, 3);
+       return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(tda829x_probe);
+
+MODULE_DESCRIPTION("Philips/NXP TDA8290/TDA8295 analog IF demodulator driver");
+MODULE_AUTHOR("Gerd Knorr, Hartmut Hackmann, Michael Krufky");
+MODULE_LICENSE("GPL");
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/tuners/tda8290.h b/drivers/media/tuners/tda8290.h
new file mode 100644 (file)
index 0000000..7e288b2
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+    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 __TDA8290_H__
+#define __TDA8290_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+struct tda829x_config {
+       unsigned int lna_cfg;
+
+       unsigned int probe_tuner:1;
+#define TDA829X_PROBE_TUNER 0
+#define TDA829X_DONT_PROBE  1
+};
+
+#if defined(CONFIG_MEDIA_TUNER_TDA8290) || (defined(CONFIG_MEDIA_TUNER_TDA8290_MODULE) && defined(MODULE))
+extern int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr);
+
+extern struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
+                                          struct i2c_adapter *i2c_adap,
+                                          u8 i2c_addr,
+                                          struct tda829x_config *cfg);
+#else
+static inline int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return -EINVAL;
+}
+
+static inline struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
+                                                 struct i2c_adapter *i2c_adap,
+                                                 u8 i2c_addr,
+                                                 struct tda829x_config *cfg)
+{
+       printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
+              __func__);
+       return NULL;
+}
+#endif
+
+#endif /* __TDA8290_H__ */
diff --git a/drivers/media/tuners/tda9887.c b/drivers/media/tuners/tda9887.c
new file mode 100644 (file)
index 0000000..cdb645d
--- /dev/null
@@ -0,0 +1,717 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <media/tuner.h>
+#include "tuner-i2c.h"
+#include "tda9887.h"
+
+
+/* Chips:
+   TDA9885 (PAL, NTSC)
+   TDA9886 (PAL, SECAM, NTSC)
+   TDA9887 (PAL, SECAM, NTSC, FM Radio)
+
+   Used as part of several tuners
+*/
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable verbose debug messages");
+
+static DEFINE_MUTEX(tda9887_list_mutex);
+static LIST_HEAD(hybrid_tuner_instance_list);
+
+struct tda9887_priv {
+       struct tuner_i2c_props i2c_props;
+       struct list_head hybrid_tuner_instance_list;
+
+       unsigned char      data[4];
+       unsigned int       config;
+       unsigned int       mode;
+       unsigned int       audmode;
+       v4l2_std_id        std;
+
+       bool               standby;
+};
+
+/* ---------------------------------------------------------------------- */
+
+#define UNSET       (-1U)
+
+struct tvnorm {
+       v4l2_std_id       std;
+       char              *name;
+       unsigned char     b;
+       unsigned char     c;
+       unsigned char     e;
+};
+
+/* ---------------------------------------------------------------------- */
+
+//
+// TDA defines
+//
+
+//// first reg (b)
+#define cVideoTrapBypassOFF     0x00    // bit b0
+#define cVideoTrapBypassON      0x01    // bit b0
+
+#define cAutoMuteFmInactive     0x00    // bit b1
+#define cAutoMuteFmActive       0x02    // bit b1
+
+#define cIntercarrier           0x00    // bit b2
+#define cQSS                    0x04    // bit b2
+
+#define cPositiveAmTV           0x00    // bit b3:4
+#define cFmRadio                0x08    // bit b3:4
+#define cNegativeFmTV           0x10    // bit b3:4
+
+
+#define cForcedMuteAudioON      0x20    // bit b5
+#define cForcedMuteAudioOFF     0x00    // bit b5
+
+#define cOutputPort1Active      0x00    // bit b6
+#define cOutputPort1Inactive    0x40    // bit b6
+
+#define cOutputPort2Active      0x00    // bit b7
+#define cOutputPort2Inactive    0x80    // bit b7
+
+
+//// second reg (c)
+#define cDeemphasisOFF          0x00    // bit c5
+#define cDeemphasisON           0x20    // bit c5
+
+#define cDeemphasis75           0x00    // bit c6
+#define cDeemphasis50           0x40    // bit c6
+
+#define cAudioGain0             0x00    // bit c7
+#define cAudioGain6             0x80    // bit c7
+
+#define cTopMask                0x1f    // bit c0:4
+#define cTopDefault            0x10    // bit c0:4
+
+//// third reg (e)
+#define cAudioIF_4_5             0x00    // bit e0:1
+#define cAudioIF_5_5             0x01    // bit e0:1
+#define cAudioIF_6_0             0x02    // bit e0:1
+#define cAudioIF_6_5             0x03    // bit e0:1
+
+
+#define cVideoIFMask           0x1c    // bit e2:4
+/* Video IF selection in TV Mode (bit B3=0) */
+#define cVideoIF_58_75           0x00    // bit e2:4
+#define cVideoIF_45_75           0x04    // bit e2:4
+#define cVideoIF_38_90           0x08    // bit e2:4
+#define cVideoIF_38_00           0x0C    // bit e2:4
+#define cVideoIF_33_90           0x10    // bit e2:4
+#define cVideoIF_33_40           0x14    // bit e2:4
+#define cRadioIF_45_75           0x18    // bit e2:4
+#define cRadioIF_38_90           0x1C    // bit e2:4
+
+/* IF1 selection in Radio Mode (bit B3=1) */
+#define cRadioIF_33_30         0x00    // bit e2,4 (also 0x10,0x14)
+#define cRadioIF_41_30         0x04    // bit e2,4
+
+/* Output of AFC pin in radio mode when bit E7=1 */
+#define cRadioAGC_SIF          0x00    // bit e3
+#define cRadioAGC_FM           0x08    // bit e3
+
+#define cTunerGainNormal         0x00    // bit e5
+#define cTunerGainLow            0x20    // bit e5
+
+#define cGating_18               0x00    // bit e6
+#define cGating_36               0x40    // bit e6
+
+#define cAgcOutON                0x80    // bit e7
+#define cAgcOutOFF               0x00    // bit e7
+
+/* ---------------------------------------------------------------------- */
+
+static struct tvnorm tvnorms[] = {
+       {
+               .std   = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N,
+               .name  = "PAL-BGHN",
+               .b     = ( cNegativeFmTV  |
+                          cQSS           ),
+               .c     = ( cDeemphasisON  |
+                          cDeemphasis50  |
+                          cTopDefault),
+               .e     = ( cGating_36     |
+                          cAudioIF_5_5   |
+                          cVideoIF_38_90 ),
+       },{
+               .std   = V4L2_STD_PAL_I,
+               .name  = "PAL-I",
+               .b     = ( cNegativeFmTV  |
+                          cQSS           ),
+               .c     = ( cDeemphasisON  |
+                          cDeemphasis50  |
+                          cTopDefault),
+               .e     = ( cGating_36     |
+                          cAudioIF_6_0   |
+                          cVideoIF_38_90 ),
+       },{
+               .std   = V4L2_STD_PAL_DK,
+               .name  = "PAL-DK",
+               .b     = ( cNegativeFmTV  |
+                          cQSS           ),
+               .c     = ( cDeemphasisON  |
+                          cDeemphasis50  |
+                          cTopDefault),
+               .e     = ( cGating_36     |
+                          cAudioIF_6_5   |
+                          cVideoIF_38_90 ),
+       },{
+               .std   = V4L2_STD_PAL_M | V4L2_STD_PAL_Nc,
+               .name  = "PAL-M/Nc",
+               .b     = ( cNegativeFmTV  |
+                          cQSS           ),
+               .c     = ( cDeemphasisON  |
+                          cDeemphasis75  |
+                          cTopDefault),
+               .e     = ( cGating_36     |
+                          cAudioIF_4_5   |
+                          cVideoIF_45_75 ),
+       },{
+               .std   = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H,
+               .name  = "SECAM-BGH",
+               .b     = ( cNegativeFmTV  |
+                          cQSS           ),
+               .c     = ( cTopDefault),
+               .e     = ( cAudioIF_5_5   |
+                          cVideoIF_38_90 ),
+       },{
+               .std   = V4L2_STD_SECAM_L,
+               .name  = "SECAM-L",
+               .b     = ( cPositiveAmTV  |
+                          cQSS           ),
+               .c     = ( cTopDefault),
+               .e     = ( cGating_36     |
+                          cAudioIF_6_5   |
+                          cVideoIF_38_90 ),
+       },{
+               .std   = V4L2_STD_SECAM_LC,
+               .name  = "SECAM-L'",
+               .b     = ( cOutputPort2Inactive |
+                          cPositiveAmTV  |
+                          cQSS           ),
+               .c     = ( cTopDefault),
+               .e     = ( cGating_36     |
+                          cAudioIF_6_5   |
+                          cVideoIF_33_90 ),
+       },{
+               .std   = V4L2_STD_SECAM_DK,
+               .name  = "SECAM-DK",
+               .b     = ( cNegativeFmTV  |
+                          cQSS           ),
+               .c     = ( cDeemphasisON  |
+                          cDeemphasis50  |
+                          cTopDefault),
+               .e     = ( cGating_36     |
+                          cAudioIF_6_5   |
+                          cVideoIF_38_90 ),
+       },{
+               .std   = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
+               .name  = "NTSC-M",
+               .b     = ( cNegativeFmTV  |
+                          cQSS           ),
+               .c     = ( cDeemphasisON  |
+                          cDeemphasis75  |
+                          cTopDefault),
+               .e     = ( cGating_36     |
+                          cAudioIF_4_5   |
+                          cVideoIF_45_75 ),
+       },{
+               .std   = V4L2_STD_NTSC_M_JP,
+               .name  = "NTSC-M-JP",
+               .b     = ( cNegativeFmTV  |
+                          cQSS           ),
+               .c     = ( cDeemphasisON  |
+                          cDeemphasis50  |
+                          cTopDefault),
+               .e     = ( cGating_36     |
+                          cAudioIF_4_5   |
+                          cVideoIF_58_75 ),
+       }
+};
+
+static struct tvnorm radio_stereo = {
+       .name = "Radio Stereo",
+       .b    = ( cFmRadio       |
+                 cQSS           ),
+       .c    = ( cDeemphasisOFF |
+                 cAudioGain6    |
+                 cTopDefault),
+       .e    = ( cTunerGainLow  |
+                 cAudioIF_5_5   |
+                 cRadioIF_38_90 ),
+};
+
+static struct tvnorm radio_mono = {
+       .name = "Radio Mono",
+       .b    = ( cFmRadio       |
+                 cQSS           ),
+       .c    = ( cDeemphasisON  |
+                 cDeemphasis75  |
+                 cTopDefault),
+       .e    = ( cTunerGainLow  |
+                 cAudioIF_5_5   |
+                 cRadioIF_38_90 ),
+};
+
+/* ---------------------------------------------------------------------- */
+
+static void dump_read_message(struct dvb_frontend *fe, unsigned char *buf)
+{
+       struct tda9887_priv *priv = fe->analog_demod_priv;
+
+       static char *afc[16] = {
+               "- 12.5 kHz",
+               "- 37.5 kHz",
+               "- 62.5 kHz",
+               "- 87.5 kHz",
+               "-112.5 kHz",
+               "-137.5 kHz",
+               "-162.5 kHz",
+               "-187.5 kHz [min]",
+               "+187.5 kHz [max]",
+               "+162.5 kHz",
+               "+137.5 kHz",
+               "+112.5 kHz",
+               "+ 87.5 kHz",
+               "+ 62.5 kHz",
+               "+ 37.5 kHz",
+               "+ 12.5 kHz",
+       };
+       tuner_info("read: 0x%2x\n", buf[0]);
+       tuner_info("  after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no");
+       tuner_info("  afc            : %s\n", afc[(buf[0] >> 1) & 0x0f]);
+       tuner_info("  fmif level     : %s\n", (buf[0] & 0x20) ? "high" : "low");
+       tuner_info("  afc window     : %s\n", (buf[0] & 0x40) ? "in" : "out");
+       tuner_info("  vfi level      : %s\n", (buf[0] & 0x80) ? "high" : "low");
+}
+
+static void dump_write_message(struct dvb_frontend *fe, unsigned char *buf)
+{
+       struct tda9887_priv *priv = fe->analog_demod_priv;
+
+       static char *sound[4] = {
+               "AM/TV",
+               "FM/radio",
+               "FM/TV",
+               "FM/radio"
+       };
+       static char *adjust[32] = {
+               "-16", "-15", "-14", "-13", "-12", "-11", "-10", "-9",
+               "-8",  "-7",  "-6",  "-5",  "-4",  "-3",  "-2",  "-1",
+               "0",   "+1",  "+2",  "+3",  "+4",  "+5",  "+6",  "+7",
+               "+8",  "+9",  "+10", "+11", "+12", "+13", "+14", "+15"
+       };
+       static char *deemph[4] = {
+               "no", "no", "75", "50"
+       };
+       static char *carrier[4] = {
+               "4.5 MHz",
+               "5.5 MHz",
+               "6.0 MHz",
+               "6.5 MHz / AM"
+       };
+       static char *vif[8] = {
+               "58.75 MHz",
+               "45.75 MHz",
+               "38.9 MHz",
+               "38.0 MHz",
+               "33.9 MHz",
+               "33.4 MHz",
+               "45.75 MHz + pin13",
+               "38.9 MHz + pin13",
+       };
+       static char *rif[4] = {
+               "44 MHz",
+               "52 MHz",
+               "52 MHz",
+               "44 MHz",
+       };
+
+       tuner_info("write: byte B 0x%02x\n", buf[1]);
+       tuner_info("  B0   video mode      : %s\n",
+                  (buf[1] & 0x01) ? "video trap" : "sound trap");
+       tuner_info("  B1   auto mute fm    : %s\n",
+                  (buf[1] & 0x02) ? "yes" : "no");
+       tuner_info("  B2   carrier mode    : %s\n",
+                  (buf[1] & 0x04) ? "QSS" : "Intercarrier");
+       tuner_info("  B3-4 tv sound/radio  : %s\n",
+                  sound[(buf[1] & 0x18) >> 3]);
+       tuner_info("  B5   force mute audio: %s\n",
+                  (buf[1] & 0x20) ? "yes" : "no");
+       tuner_info("  B6   output port 1   : %s\n",
+                  (buf[1] & 0x40) ? "high (inactive)" : "low (active)");
+       tuner_info("  B7   output port 2   : %s\n",
+                  (buf[1] & 0x80) ? "high (inactive)" : "low (active)");
+
+       tuner_info("write: byte C 0x%02x\n", buf[2]);
+       tuner_info("  C0-4 top adjustment  : %s dB\n",
+                  adjust[buf[2] & 0x1f]);
+       tuner_info("  C5-6 de-emphasis     : %s\n",
+                  deemph[(buf[2] & 0x60) >> 5]);
+       tuner_info("  C7   audio gain      : %s\n",
+                  (buf[2] & 0x80) ? "-6" : "0");
+
+       tuner_info("write: byte E 0x%02x\n", buf[3]);
+       tuner_info("  E0-1 sound carrier   : %s\n",
+                  carrier[(buf[3] & 0x03)]);
+       tuner_info("  E6   l pll gating   : %s\n",
+                  (buf[3] & 0x40) ? "36" : "13");
+
+       if (buf[1] & 0x08) {
+               /* radio */
+               tuner_info("  E2-4 video if        : %s\n",
+                          rif[(buf[3] & 0x0c) >> 2]);
+               tuner_info("  E7   vif agc output  : %s\n",
+                          (buf[3] & 0x80)
+                          ? ((buf[3] & 0x10) ? "fm-agc radio" :
+                                               "sif-agc radio")
+                          : "fm radio carrier afc");
+       } else {
+               /* video */
+               tuner_info("  E2-4 video if        : %s\n",
+                          vif[(buf[3] & 0x1c) >> 2]);
+               tuner_info("  E5   tuner gain      : %s\n",
+                          (buf[3] & 0x80)
+                          ? ((buf[3] & 0x20) ? "external" : "normal")
+                          : ((buf[3] & 0x20) ? "minimum"  : "normal"));
+               tuner_info("  E7   vif agc output  : %s\n",
+                          (buf[3] & 0x80) ? ((buf[3] & 0x20)
+                               ? "pin3 port, pin22 vif agc out"
+                               : "pin22 port, pin3 vif acg ext in")
+                               : "pin3+pin22 port");
+       }
+       tuner_info("--\n");
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int tda9887_set_tvnorm(struct dvb_frontend *fe)
+{
+       struct tda9887_priv *priv = fe->analog_demod_priv;
+       struct tvnorm *norm = NULL;
+       char *buf = priv->data;
+       int i;
+
+       if (priv->mode == V4L2_TUNER_RADIO) {
+               if (priv->audmode == V4L2_TUNER_MODE_MONO)
+                       norm = &radio_mono;
+               else
+                       norm = &radio_stereo;
+       } else {
+               for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
+                       if (tvnorms[i].std & priv->std) {
+                               norm = tvnorms+i;
+                               break;
+                       }
+               }
+       }
+       if (NULL == norm) {
+               tuner_dbg("Unsupported tvnorm entry - audio muted\n");
+               return -1;
+       }
+
+       tuner_dbg("configure for: %s\n", norm->name);
+       buf[1] = norm->b;
+       buf[2] = norm->c;
+       buf[3] = norm->e;
+       return 0;
+}
+
+static unsigned int port1  = UNSET;
+static unsigned int port2  = UNSET;
+static unsigned int qss    = UNSET;
+static unsigned int adjust = UNSET;
+
+module_param(port1, int, 0644);
+module_param(port2, int, 0644);
+module_param(qss, int, 0644);
+module_param(adjust, int, 0644);
+
+static int tda9887_set_insmod(struct dvb_frontend *fe)
+{
+       struct tda9887_priv *priv = fe->analog_demod_priv;
+       char *buf = priv->data;
+
+       if (UNSET != port1) {
+               if (port1)
+                       buf[1] |= cOutputPort1Inactive;
+               else
+                       buf[1] &= ~cOutputPort1Inactive;
+       }
+       if (UNSET != port2) {
+               if (port2)
+                       buf[1] |= cOutputPort2Inactive;
+               else
+                       buf[1] &= ~cOutputPort2Inactive;
+       }
+
+       if (UNSET != qss) {
+               if (qss)
+                       buf[1] |= cQSS;
+               else
+                       buf[1] &= ~cQSS;
+       }
+
+       if (adjust < 0x20) {
+               buf[2] &= ~cTopMask;
+               buf[2] |= adjust;
+       }
+       return 0;
+}
+
+static int tda9887_do_config(struct dvb_frontend *fe)
+{
+       struct tda9887_priv *priv = fe->analog_demod_priv;
+       char *buf = priv->data;
+
+       if (priv->config & TDA9887_PORT1_ACTIVE)
+               buf[1] &= ~cOutputPort1Inactive;
+       if (priv->config & TDA9887_PORT1_INACTIVE)
+               buf[1] |= cOutputPort1Inactive;
+       if (priv->config & TDA9887_PORT2_ACTIVE)
+               buf[1] &= ~cOutputPort2Inactive;
+       if (priv->config & TDA9887_PORT2_INACTIVE)
+               buf[1] |= cOutputPort2Inactive;
+
+       if (priv->config & TDA9887_QSS)
+               buf[1] |= cQSS;
+       if (priv->config & TDA9887_INTERCARRIER)
+               buf[1] &= ~cQSS;
+
+       if (priv->config & TDA9887_AUTOMUTE)
+               buf[1] |= cAutoMuteFmActive;
+       if (priv->config & TDA9887_DEEMPHASIS_MASK) {
+               buf[2] &= ~0x60;
+               switch (priv->config & TDA9887_DEEMPHASIS_MASK) {
+               case TDA9887_DEEMPHASIS_NONE:
+                       buf[2] |= cDeemphasisOFF;
+                       break;
+               case TDA9887_DEEMPHASIS_50:
+                       buf[2] |= cDeemphasisON | cDeemphasis50;
+                       break;
+               case TDA9887_DEEMPHASIS_75:
+                       buf[2] |= cDeemphasisON | cDeemphasis75;
+                       break;
+               }
+       }
+       if (priv->config & TDA9887_TOP_SET) {
+               buf[2] &= ~cTopMask;
+               buf[2] |= (priv->config >> 8) & cTopMask;
+       }
+       if ((priv->config & TDA9887_INTERCARRIER_NTSC) &&
+           (priv->std & V4L2_STD_NTSC))
+               buf[1] &= ~cQSS;
+       if (priv->config & TDA9887_GATING_18)
+               buf[3] &= ~cGating_36;
+
+       if (priv->mode == V4L2_TUNER_RADIO) {
+               if (priv->config & TDA9887_RIF_41_3) {
+                       buf[3] &= ~cVideoIFMask;
+                       buf[3] |= cRadioIF_41_30;
+               }
+               if (priv->config & TDA9887_GAIN_NORMAL)
+                       buf[3] &= ~cTunerGainLow;
+       }
+
+       return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int tda9887_status(struct dvb_frontend *fe)
+{
+       struct tda9887_priv *priv = fe->analog_demod_priv;
+       unsigned char buf[1];
+       int rc;
+
+       memset(buf,0,sizeof(buf));
+       if (1 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props,buf,1)))
+               tuner_info("i2c i/o error: rc == %d (should be 1)\n", rc);
+       dump_read_message(fe, buf);
+       return 0;
+}
+
+static void tda9887_configure(struct dvb_frontend *fe)
+{
+       struct tda9887_priv *priv = fe->analog_demod_priv;
+       int rc;
+
+       memset(priv->data,0,sizeof(priv->data));
+       tda9887_set_tvnorm(fe);
+
+       /* A note on the port settings:
+          These settings tend to depend on the specifics of the board.
+          By default they are set to inactive (bit value 1) by this driver,
+          overwriting any changes made by the tvnorm. This means that it
+          is the responsibility of the module using the tda9887 to set
+          these values in case of changes in the tvnorm.
+          In many cases port 2 should be made active (0) when selecting
+          SECAM-L, and port 2 should remain inactive (1) for SECAM-L'.
+
+          For the other standards the tda9887 application note says that
+          the ports should be set to active (0), but, again, that may
+          differ depending on the precise hardware configuration.
+        */
+       priv->data[1] |= cOutputPort1Inactive;
+       priv->data[1] |= cOutputPort2Inactive;
+
+       tda9887_do_config(fe);
+       tda9887_set_insmod(fe);
+
+       if (priv->standby)
+               priv->data[1] |= cForcedMuteAudioON;
+
+       tuner_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
+                 priv->data[1], priv->data[2], priv->data[3]);
+       if (debug > 1)
+               dump_write_message(fe, priv->data);
+
+       if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,priv->data,4)))
+               tuner_info("i2c i/o error: rc == %d (should be 4)\n", rc);
+
+       if (debug > 2) {
+               msleep_interruptible(1000);
+               tda9887_status(fe);
+       }
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void tda9887_tuner_status(struct dvb_frontend *fe)
+{
+       struct tda9887_priv *priv = fe->analog_demod_priv;
+       tuner_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n",
+                  priv->data[1], priv->data[2], priv->data[3]);
+}
+
+static int tda9887_get_afc(struct dvb_frontend *fe)
+{
+       struct tda9887_priv *priv = fe->analog_demod_priv;
+       static int AFC_BITS_2_kHz[] = {
+               -12500,  -37500,  -62500,  -97500,
+               -112500, -137500, -162500, -187500,
+               187500,  162500,  137500,  112500,
+               97500 ,  62500,   37500 ,  12500
+       };
+       int afc=0;
+       __u8 reg = 0;
+
+       if (1 == tuner_i2c_xfer_recv(&priv->i2c_props,&reg,1))
+               afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];
+
+       return afc;
+}
+
+static void tda9887_standby(struct dvb_frontend *fe)
+{
+       struct tda9887_priv *priv = fe->analog_demod_priv;
+
+       priv->standby = true;
+
+       tda9887_configure(fe);
+}
+
+static void tda9887_set_params(struct dvb_frontend *fe,
+                              struct analog_parameters *params)
+{
+       struct tda9887_priv *priv = fe->analog_demod_priv;
+
+       priv->standby = false;
+       priv->mode    = params->mode;
+       priv->audmode = params->audmode;
+       priv->std     = params->std;
+       tda9887_configure(fe);
+}
+
+static int tda9887_set_config(struct dvb_frontend *fe, void *priv_cfg)
+{
+       struct tda9887_priv *priv = fe->analog_demod_priv;
+
+       priv->config = *(unsigned int *)priv_cfg;
+       tda9887_configure(fe);
+
+       return 0;
+}
+
+static void tda9887_release(struct dvb_frontend *fe)
+{
+       struct tda9887_priv *priv = fe->analog_demod_priv;
+
+       mutex_lock(&tda9887_list_mutex);
+
+       if (priv)
+               hybrid_tuner_release_state(priv);
+
+       mutex_unlock(&tda9887_list_mutex);
+
+       fe->analog_demod_priv = NULL;
+}
+
+static struct analog_demod_ops tda9887_ops = {
+       .info           = {
+               .name   = "tda9887",
+       },
+       .set_params     = tda9887_set_params,
+       .standby        = tda9887_standby,
+       .tuner_status   = tda9887_tuner_status,
+       .get_afc        = tda9887_get_afc,
+       .release        = tda9887_release,
+       .set_config     = tda9887_set_config,
+};
+
+struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
+                                   struct i2c_adapter *i2c_adap,
+                                   u8 i2c_addr)
+{
+       struct tda9887_priv *priv = NULL;
+       int instance;
+
+       mutex_lock(&tda9887_list_mutex);
+
+       instance = hybrid_tuner_request_state(struct tda9887_priv, priv,
+                                             hybrid_tuner_instance_list,
+                                             i2c_adap, i2c_addr, "tda9887");
+       switch (instance) {
+       case 0:
+               mutex_unlock(&tda9887_list_mutex);
+               return NULL;
+       case 1:
+               fe->analog_demod_priv = priv;
+               priv->standby = true;
+               tuner_info("tda988[5/6/7] found\n");
+               break;
+       default:
+               fe->analog_demod_priv = priv;
+               break;
+       }
+
+       mutex_unlock(&tda9887_list_mutex);
+
+       memcpy(&fe->ops.analog_ops, &tda9887_ops,
+              sizeof(struct analog_demod_ops));
+
+       return fe;
+}
+EXPORT_SYMBOL_GPL(tda9887_attach);
+
+MODULE_LICENSE("GPL");
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/tuners/tda9887.h b/drivers/media/tuners/tda9887.h
new file mode 100644 (file)
index 0000000..acc419e
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    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 __TDA9887_H__
+#define __TDA9887_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+/* ------------------------------------------------------------------------ */
+#if defined(CONFIG_MEDIA_TUNER_TDA9887) || (defined(CONFIG_MEDIA_TUNER_TDA9887_MODULE) && defined(MODULE))
+extern struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
+                                          struct i2c_adapter *i2c_adap,
+                                          u8 i2c_addr);
+#else
+static inline struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
+                                                 struct i2c_adapter *i2c_adap,
+                                                 u8 i2c_addr)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* __TDA9887_H__ */
diff --git a/drivers/media/tuners/tea5761.c b/drivers/media/tuners/tea5761.c
new file mode 100644 (file)
index 0000000..bf78cb9
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ * For Philips TEA5761 FM Chip
+ * I2C address is allways 0x20 (0x10 at 7-bit mode).
+ *
+ * Copyright (c) 2005-2007 Mauro Carvalho Chehab (mchehab@infradead.org)
+ * This code is placed under the terms of the GNUv2 General Public License
+ *
+ */
+
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <media/tuner.h>
+#include "tuner-i2c.h"
+#include "tea5761.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable verbose debug messages");
+
+struct tea5761_priv {
+       struct tuner_i2c_props i2c_props;
+
+       u32 frequency;
+       bool standby;
+};
+
+/*****************************************************************************/
+
+/***************************
+ * TEA5761HN I2C registers *
+ ***************************/
+
+/* INTREG - Read: bytes 0 and 1 / Write: byte 0 */
+
+       /* first byte for reading */
+#define TEA5761_INTREG_IFFLAG          0x10
+#define TEA5761_INTREG_LEVFLAG         0x8
+#define TEA5761_INTREG_FRRFLAG         0x2
+#define TEA5761_INTREG_BLFLAG          0x1
+
+       /* second byte for reading / byte for writing */
+#define TEA5761_INTREG_IFMSK           0x10
+#define TEA5761_INTREG_LEVMSK          0x8
+#define TEA5761_INTREG_FRMSK           0x2
+#define TEA5761_INTREG_BLMSK           0x1
+
+/* FRQSET - Read: bytes 2 and 3 / Write: byte 1 and 2 */
+
+       /* First byte */
+#define TEA5761_FRQSET_SEARCH_UP 0x80          /* 1=Station search from botton to up */
+#define TEA5761_FRQSET_SEARCH_MODE 0x40                /* 1=Search mode */
+
+       /* Bits 0-5 for divider MSB */
+
+       /* Second byte */
+       /* Bits 0-7 for divider LSB */
+
+/* TNCTRL - Read: bytes 4 and 5 / Write: Bytes 3 and 4 */
+
+       /* first byte */
+
+#define TEA5761_TNCTRL_PUPD_0  0x40    /* Power UP/Power Down MSB */
+#define TEA5761_TNCTRL_BLIM    0X20    /* 1= Japan Frequencies, 0= European frequencies */
+#define TEA5761_TNCTRL_SWPM    0x10    /* 1= software port is FRRFLAG */
+#define TEA5761_TNCTRL_IFCTC   0x08    /* 1= IF count time 15.02 ms, 0= IF count time 2.02 ms */
+#define TEA5761_TNCTRL_AFM     0x04
+#define TEA5761_TNCTRL_SMUTE   0x02    /* 1= Soft mute */
+#define TEA5761_TNCTRL_SNC     0x01
+
+       /* second byte */
+
+#define TEA5761_TNCTRL_MU      0x80    /* 1=Hard mute */
+#define TEA5761_TNCTRL_SSL_1   0x40
+#define TEA5761_TNCTRL_SSL_0   0x20
+#define TEA5761_TNCTRL_HLSI    0x10
+#define TEA5761_TNCTRL_MST     0x08    /* 1 = mono */
+#define TEA5761_TNCTRL_SWP     0x04
+#define TEA5761_TNCTRL_DTC     0x02    /* 1 = deemphasis 50 us, 0 = deemphasis 75 us */
+#define TEA5761_TNCTRL_AHLSI   0x01
+
+/* FRQCHECK - Read: bytes 6 and 7  */
+       /* First byte */
+
+       /* Bits 0-5 for divider MSB */
+
+       /* Second byte */
+       /* Bits 0-7 for divider LSB */
+
+/* TUNCHECK - Read: bytes 8 and 9  */
+
+       /* First byte */
+#define TEA5761_TUNCHECK_IF_MASK       0x7e    /* IF count */
+#define TEA5761_TUNCHECK_TUNTO         0x01
+
+       /* Second byte */
+#define TEA5761_TUNCHECK_LEV_MASK      0xf0    /* Level Count */
+#define TEA5761_TUNCHECK_LD            0x08
+#define TEA5761_TUNCHECK_STEREO                0x04
+
+/* TESTREG - Read: bytes 10 and 11 / Write: bytes 5 and 6 */
+
+       /* All zero = no test mode */
+
+/* MANID - Read: bytes 12 and 13 */
+
+       /* First byte - should be 0x10 */
+#define TEA5767_MANID_VERSION_MASK     0xf0    /* Version = 1 */
+#define TEA5767_MANID_ID_MSB_MASK      0x0f    /* Manufacurer ID - should be 0 */
+
+       /* Second byte - Should be 0x2b */
+
+#define TEA5767_MANID_ID_LSB_MASK      0xfe    /* Manufacturer ID - should be 0x15 */
+#define TEA5767_MANID_IDAV             0x01    /* 1 = Chip has ID, 0 = Chip has no ID */
+
+/* Chip ID - Read: bytes 14 and 15 */
+
+       /* First byte - should be 0x57 */
+
+       /* Second byte - should be 0x61 */
+
+/*****************************************************************************/
+
+#define FREQ_OFFSET 0 /* for TEA5767, it is 700 to give the right freq */
+static void tea5761_status_dump(unsigned char *buffer)
+{
+       unsigned int div, frq;
+
+       div = ((buffer[2] & 0x3f) << 8) | buffer[3];
+
+       frq = 1000 * (div * 32768 / 1000 + FREQ_OFFSET + 225) / 4;      /* Freq in KHz */
+
+       printk(KERN_INFO "tea5761: Frequency %d.%03d KHz (divider = 0x%04x)\n",
+              frq / 1000, frq % 1000, div);
+}
+
+/* Freq should be specifyed at 62.5 Hz */
+static int __set_radio_freq(struct dvb_frontend *fe,
+                           unsigned int freq,
+                           bool mono)
+{
+       struct tea5761_priv *priv = fe->tuner_priv;
+       unsigned int frq = freq;
+       unsigned char buffer[7] = {0, 0, 0, 0, 0, 0, 0 };
+       unsigned div;
+       int rc;
+
+       tuner_dbg("radio freq counter %d\n", frq);
+
+       if (priv->standby) {
+               tuner_dbg("TEA5761 set to standby mode\n");
+               buffer[5] |= TEA5761_TNCTRL_MU;
+       } else {
+               buffer[4] |= TEA5761_TNCTRL_PUPD_0;
+       }
+
+
+       if (mono) {
+               tuner_dbg("TEA5761 set to mono\n");
+               buffer[5] |= TEA5761_TNCTRL_MST;
+       } else {
+               tuner_dbg("TEA5761 set to stereo\n");
+       }
+
+       div = (1000 * (frq * 4 / 16 + 700 + 225) ) >> 15;
+       buffer[1] = (div >> 8) & 0x3f;
+       buffer[2] = div & 0xff;
+
+       if (debug)
+               tea5761_status_dump(buffer);
+
+       if (7 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 7)))
+               tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+
+       priv->frequency = frq * 125 / 2;
+
+       return 0;
+}
+
+static int set_radio_freq(struct dvb_frontend *fe,
+                         struct analog_parameters *params)
+{
+       struct tea5761_priv *priv = fe->analog_demod_priv;
+
+       priv->standby = false;
+
+       return __set_radio_freq(fe, params->frequency,
+                               params->audmode == V4L2_TUNER_MODE_MONO);
+}
+
+static int set_radio_sleep(struct dvb_frontend *fe)
+{
+       struct tea5761_priv *priv = fe->analog_demod_priv;
+
+       priv->standby = true;
+
+       return __set_radio_freq(fe, priv->frequency, false);
+}
+
+static int tea5761_read_status(struct dvb_frontend *fe, char *buffer)
+{
+       struct tea5761_priv *priv = fe->tuner_priv;
+       int rc;
+
+       memset(buffer, 0, 16);
+       if (16 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 16))) {
+               tuner_warn("i2c i/o error: rc == %d (should be 16)\n", rc);
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static inline int tea5761_signal(struct dvb_frontend *fe, const char *buffer)
+{
+       struct tea5761_priv *priv = fe->tuner_priv;
+
+       int signal = ((buffer[9] & TEA5761_TUNCHECK_LEV_MASK) << (13 - 4));
+
+       tuner_dbg("Signal strength: %d\n", signal);
+
+       return signal;
+}
+
+static inline int tea5761_stereo(struct dvb_frontend *fe, const char *buffer)
+{
+       struct tea5761_priv *priv = fe->tuner_priv;
+
+       int stereo = buffer[9] & TEA5761_TUNCHECK_STEREO;
+
+       tuner_dbg("Radio ST GET = %02x\n", stereo);
+
+       return (stereo ? V4L2_TUNER_SUB_STEREO : 0);
+}
+
+static int tea5761_get_status(struct dvb_frontend *fe, u32 *status)
+{
+       unsigned char buffer[16];
+
+       *status = 0;
+
+       if (0 == tea5761_read_status(fe, buffer)) {
+               if (tea5761_signal(fe, buffer))
+                       *status = TUNER_STATUS_LOCKED;
+               if (tea5761_stereo(fe, buffer))
+                       *status |= TUNER_STATUS_STEREO;
+       }
+
+       return 0;
+}
+
+static int tea5761_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       unsigned char buffer[16];
+
+       *strength = 0;
+
+       if (0 == tea5761_read_status(fe, buffer))
+               *strength = tea5761_signal(fe, buffer);
+
+       return 0;
+}
+
+int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr)
+{
+       unsigned char buffer[16];
+       int rc;
+       struct tuner_i2c_props i2c = { .adap = i2c_adap, .addr = i2c_addr };
+
+       if (16 != (rc = tuner_i2c_xfer_recv(&i2c, buffer, 16))) {
+               printk(KERN_WARNING "it is not a TEA5761. Received %i chars.\n", rc);
+               return -EINVAL;
+       }
+
+       if ((buffer[13] != 0x2b) || (buffer[14] != 0x57) || (buffer[15] != 0x061)) {
+               printk(KERN_WARNING "Manufacturer ID= 0x%02x, Chip ID = %02x%02x."
+                                   " It is not a TEA5761\n",
+                                   buffer[13], buffer[14], buffer[15]);
+               return -EINVAL;
+       }
+       printk(KERN_WARNING "tea5761: TEA%02x%02x detected. "
+                           "Manufacturer ID= 0x%02x\n",
+                           buffer[14], buffer[15], buffer[13]);
+
+       return 0;
+}
+
+static int tea5761_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+
+       return 0;
+}
+
+static int tea5761_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct tea5761_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static struct dvb_tuner_ops tea5761_tuner_ops = {
+       .info = {
+               .name           = "tea5761", // Philips TEA5761HN FM Radio
+       },
+       .set_analog_params = set_radio_freq,
+       .sleep             = set_radio_sleep,
+       .release           = tea5761_release,
+       .get_frequency     = tea5761_get_frequency,
+       .get_status        = tea5761_get_status,
+       .get_rf_strength   = tea5761_get_rf_strength,
+};
+
+struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe,
+                                   struct i2c_adapter* i2c_adap,
+                                   u8 i2c_addr)
+{
+       struct tea5761_priv *priv = NULL;
+
+       if (tea5761_autodetection(i2c_adap, i2c_addr) != 0)
+               return NULL;
+
+       priv = kzalloc(sizeof(struct tea5761_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+       fe->tuner_priv = priv;
+
+       priv->i2c_props.addr = i2c_addr;
+       priv->i2c_props.adap = i2c_adap;
+       priv->i2c_props.name = "tea5761";
+
+       memcpy(&fe->ops.tuner_ops, &tea5761_tuner_ops,
+              sizeof(struct dvb_tuner_ops));
+
+       tuner_info("type set to %s\n", "Philips TEA5761HN FM Radio");
+
+       return fe;
+}
+
+
+EXPORT_SYMBOL_GPL(tea5761_attach);
+EXPORT_SYMBOL_GPL(tea5761_autodetection);
+
+MODULE_DESCRIPTION("Philips TEA5761 FM tuner driver");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/tea5761.h b/drivers/media/tuners/tea5761.h
new file mode 100644 (file)
index 0000000..2e2ff82
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+    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 __TEA5761_H__
+#define __TEA5761_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+#if defined(CONFIG_MEDIA_TUNER_TEA5761) || (defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE) && defined(MODULE))
+extern int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr);
+
+extern struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe,
+                                          struct i2c_adapter* i2c_adap,
+                                          u8 i2c_addr);
+#else
+static inline int tea5761_autodetection(struct i2c_adapter* i2c_adap,
+                                       u8 i2c_addr)
+{
+       printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
+              __func__);
+       return -EINVAL;
+}
+
+static inline struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe,
+                                                  struct i2c_adapter* i2c_adap,
+                                                  u8 i2c_addr)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* __TEA5761_H__ */
diff --git a/drivers/media/tuners/tea5767.c b/drivers/media/tuners/tea5767.c
new file mode 100644 (file)
index 0000000..36e85d8
--- /dev/null
@@ -0,0 +1,475 @@
+/*
+ * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
+ * I2C address is allways 0xC0.
+ *
+ *
+ * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org)
+ * This code is placed under the terms of the GNU General Public License
+ *
+ * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa
+ * from their contributions on DScaler.
+ */
+
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include "tuner-i2c.h"
+#include "tea5767.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable verbose debug messages");
+
+/*****************************************************************************/
+
+struct tea5767_priv {
+       struct tuner_i2c_props  i2c_props;
+       u32                     frequency;
+       struct tea5767_ctrl     ctrl;
+};
+
+/*****************************************************************************/
+
+/******************************
+ * Write mode register values *
+ ******************************/
+
+/* First register */
+#define TEA5767_MUTE           0x80    /* Mutes output */
+#define TEA5767_SEARCH         0x40    /* Activates station search */
+/* Bits 0-5 for divider MSB */
+
+/* Second register */
+/* Bits 0-7 for divider LSB */
+
+/* Third register */
+
+/* Station search from botton to up */
+#define TEA5767_SEARCH_UP      0x80
+
+/* Searches with ADC output = 10 */
+#define TEA5767_SRCH_HIGH_LVL  0x60
+
+/* Searches with ADC output = 10 */
+#define TEA5767_SRCH_MID_LVL   0x40
+
+/* Searches with ADC output = 5 */
+#define TEA5767_SRCH_LOW_LVL   0x20
+
+/* if on, div=4*(Frf+Fif)/Fref otherwise, div=4*(Frf-Fif)/Freq) */
+#define TEA5767_HIGH_LO_INJECT 0x10
+
+/* Disable stereo */
+#define TEA5767_MONO           0x08
+
+/* Disable right channel and turns to mono */
+#define TEA5767_MUTE_RIGHT     0x04
+
+/* Disable left channel and turns to mono */
+#define TEA5767_MUTE_LEFT      0x02
+
+#define TEA5767_PORT1_HIGH     0x01
+
+/* Fourth register */
+#define TEA5767_PORT2_HIGH     0x80
+/* Chips stops working. Only I2C bus remains on */
+#define TEA5767_STDBY          0x40
+
+/* Japan freq (76-108 MHz. If disabled, 87.5-108 MHz */
+#define TEA5767_JAPAN_BAND     0x20
+
+/* Unselected means 32.768 KHz freq as reference. Otherwise Xtal at 13 MHz */
+#define TEA5767_XTAL_32768     0x10
+
+/* Cuts weak signals */
+#define TEA5767_SOFT_MUTE      0x08
+
+/* Activates high cut control */
+#define TEA5767_HIGH_CUT_CTRL  0x04
+
+/* Activates stereo noise control */
+#define TEA5767_ST_NOISE_CTL   0x02
+
+/* If activate PORT 1 indicates SEARCH or else it is used as PORT1 */
+#define TEA5767_SRCH_IND       0x01
+
+/* Fifth register */
+
+/* By activating, it will use Xtal at 13 MHz as reference for divider */
+#define TEA5767_PLLREF_ENABLE  0x80
+
+/* By activating, deemphasis=50, or else, deemphasis of 50us */
+#define TEA5767_DEEMPH_75      0X40
+
+/*****************************
+ * Read mode register values *
+ *****************************/
+
+/* First register */
+#define TEA5767_READY_FLAG_MASK        0x80
+#define TEA5767_BAND_LIMIT_MASK        0X40
+/* Bits 0-5 for divider MSB after search or preset */
+
+/* Second register */
+/* Bits 0-7 for divider LSB after search or preset */
+
+/* Third register */
+#define TEA5767_STEREO_MASK    0x80
+#define TEA5767_IF_CNTR_MASK   0x7f
+
+/* Fourth register */
+#define TEA5767_ADC_LEVEL_MASK 0xf0
+
+/* should be 0 */
+#define TEA5767_CHIP_ID_MASK   0x0f
+
+/* Fifth register */
+/* Reserved for future extensions */
+#define TEA5767_RESERVED_MASK  0xff
+
+/*****************************************************************************/
+
+static void tea5767_status_dump(struct tea5767_priv *priv,
+                               unsigned char *buffer)
+{
+       unsigned int div, frq;
+
+       if (TEA5767_READY_FLAG_MASK & buffer[0])
+               tuner_info("Ready Flag ON\n");
+       else
+               tuner_info("Ready Flag OFF\n");
+
+       if (TEA5767_BAND_LIMIT_MASK & buffer[0])
+               tuner_info("Tuner at band limit\n");
+       else
+               tuner_info("Tuner not at band limit\n");
+
+       div = ((buffer[0] & 0x3f) << 8) | buffer[1];
+
+       switch (priv->ctrl.xtal_freq) {
+       case TEA5767_HIGH_LO_13MHz:
+               frq = (div * 50000 - 700000 - 225000) / 4;      /* Freq in KHz */
+               break;
+       case TEA5767_LOW_LO_13MHz:
+               frq = (div * 50000 + 700000 + 225000) / 4;      /* Freq in KHz */
+               break;
+       case TEA5767_LOW_LO_32768:
+               frq = (div * 32768 + 700000 + 225000) / 4;      /* Freq in KHz */
+               break;
+       case TEA5767_HIGH_LO_32768:
+       default:
+               frq = (div * 32768 - 700000 - 225000) / 4;      /* Freq in KHz */
+               break;
+       }
+       buffer[0] = (div >> 8) & 0x3f;
+       buffer[1] = div & 0xff;
+
+       tuner_info("Frequency %d.%03d KHz (divider = 0x%04x)\n",
+                  frq / 1000, frq % 1000, div);
+
+       if (TEA5767_STEREO_MASK & buffer[2])
+               tuner_info("Stereo\n");
+       else
+               tuner_info("Mono\n");
+
+       tuner_info("IF Counter = %d\n", buffer[2] & TEA5767_IF_CNTR_MASK);
+
+       tuner_info("ADC Level = %d\n",
+                  (buffer[3] & TEA5767_ADC_LEVEL_MASK) >> 4);
+
+       tuner_info("Chip ID = %d\n", (buffer[3] & TEA5767_CHIP_ID_MASK));
+
+       tuner_info("Reserved = 0x%02x\n",
+                  (buffer[4] & TEA5767_RESERVED_MASK));
+}
+
+/* Freq should be specifyed at 62.5 Hz */
+static int set_radio_freq(struct dvb_frontend *fe,
+                         struct analog_parameters *params)
+{
+       struct tea5767_priv *priv = fe->tuner_priv;
+       unsigned int frq = params->frequency;
+       unsigned char buffer[5];
+       unsigned div;
+       int rc;
+
+       tuner_dbg("radio freq = %d.%03d MHz\n", frq/16000,(frq/16)%1000);
+
+       buffer[2] = 0;
+
+       if (priv->ctrl.port1)
+               buffer[2] |= TEA5767_PORT1_HIGH;
+
+       if (params->audmode == V4L2_TUNER_MODE_MONO) {
+               tuner_dbg("TEA5767 set to mono\n");
+               buffer[2] |= TEA5767_MONO;
+       } else {
+               tuner_dbg("TEA5767 set to stereo\n");
+       }
+
+
+       buffer[3] = 0;
+
+       if (priv->ctrl.port2)
+               buffer[3] |= TEA5767_PORT2_HIGH;
+
+       if (priv->ctrl.high_cut)
+               buffer[3] |= TEA5767_HIGH_CUT_CTRL;
+
+       if (priv->ctrl.st_noise)
+               buffer[3] |= TEA5767_ST_NOISE_CTL;
+
+       if (priv->ctrl.soft_mute)
+               buffer[3] |= TEA5767_SOFT_MUTE;
+
+       if (priv->ctrl.japan_band)
+               buffer[3] |= TEA5767_JAPAN_BAND;
+
+       buffer[4] = 0;
+
+       if (priv->ctrl.deemph_75)
+               buffer[4] |= TEA5767_DEEMPH_75;
+
+       if (priv->ctrl.pllref)
+               buffer[4] |= TEA5767_PLLREF_ENABLE;
+
+
+       /* Rounds freq to next decimal value - for 62.5 KHz step */
+       /* frq = 20*(frq/16)+radio_frq[frq%16]; */
+
+       switch (priv->ctrl.xtal_freq) {
+       case TEA5767_HIGH_LO_13MHz:
+               tuner_dbg("radio HIGH LO inject xtal @ 13 MHz\n");
+               buffer[2] |= TEA5767_HIGH_LO_INJECT;
+               div = (frq * (4000 / 16) + 700000 + 225000 + 25000) / 50000;
+               break;
+       case TEA5767_LOW_LO_13MHz:
+               tuner_dbg("radio LOW LO inject xtal @ 13 MHz\n");
+
+               div = (frq * (4000 / 16) - 700000 - 225000 + 25000) / 50000;
+               break;
+       case TEA5767_LOW_LO_32768:
+               tuner_dbg("radio LOW LO inject xtal @ 32,768 MHz\n");
+               buffer[3] |= TEA5767_XTAL_32768;
+               /* const 700=4000*175 Khz - to adjust freq to right value */
+               div = ((frq * (4000 / 16) - 700000 - 225000) + 16384) >> 15;
+               break;
+       case TEA5767_HIGH_LO_32768:
+       default:
+               tuner_dbg("radio HIGH LO inject xtal @ 32,768 MHz\n");
+
+               buffer[2] |= TEA5767_HIGH_LO_INJECT;
+               buffer[3] |= TEA5767_XTAL_32768;
+               div = ((frq * (4000 / 16) + 700000 + 225000) + 16384) >> 15;
+               break;
+       }
+       buffer[0] = (div >> 8) & 0x3f;
+       buffer[1] = div & 0xff;
+
+       if (5 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 5)))
+               tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+
+       if (debug) {
+               if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5)))
+                       tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+               else
+                       tea5767_status_dump(priv, buffer);
+       }
+
+       priv->frequency = frq * 125 / 2;
+
+       return 0;
+}
+
+static int tea5767_read_status(struct dvb_frontend *fe, char *buffer)
+{
+       struct tea5767_priv *priv = fe->tuner_priv;
+       int rc;
+
+       memset(buffer, 0, 5);
+       if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5))) {
+               tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static inline int tea5767_signal(struct dvb_frontend *fe, const char *buffer)
+{
+       struct tea5767_priv *priv = fe->tuner_priv;
+
+       int signal = ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << 8);
+
+       tuner_dbg("Signal strength: %d\n", signal);
+
+       return signal;
+}
+
+static inline int tea5767_stereo(struct dvb_frontend *fe, const char *buffer)
+{
+       struct tea5767_priv *priv = fe->tuner_priv;
+
+       int stereo = buffer[2] & TEA5767_STEREO_MASK;
+
+       tuner_dbg("Radio ST GET = %02x\n", stereo);
+
+       return (stereo ? V4L2_TUNER_SUB_STEREO : 0);
+}
+
+static int tea5767_get_status(struct dvb_frontend *fe, u32 *status)
+{
+       unsigned char buffer[5];
+
+       *status = 0;
+
+       if (0 == tea5767_read_status(fe, buffer)) {
+               if (tea5767_signal(fe, buffer))
+                       *status = TUNER_STATUS_LOCKED;
+               if (tea5767_stereo(fe, buffer))
+                       *status |= TUNER_STATUS_STEREO;
+       }
+
+       return 0;
+}
+
+static int tea5767_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       unsigned char buffer[5];
+
+       *strength = 0;
+
+       if (0 == tea5767_read_status(fe, buffer))
+               *strength = tea5767_signal(fe, buffer);
+
+       return 0;
+}
+
+static int tea5767_standby(struct dvb_frontend *fe)
+{
+       unsigned char buffer[5];
+       struct tea5767_priv *priv = fe->tuner_priv;
+       unsigned div, rc;
+
+       div = (87500 * 4 + 700 + 225 + 25) / 50; /* Set frequency to 87.5 MHz */
+       buffer[0] = (div >> 8) & 0x3f;
+       buffer[1] = div & 0xff;
+       buffer[2] = TEA5767_PORT1_HIGH;
+       buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL |
+                   TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND | TEA5767_STDBY;
+       buffer[4] = 0;
+
+       if (5 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 5)))
+               tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+
+       return 0;
+}
+
+int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr)
+{
+       struct tuner_i2c_props i2c = { .adap = i2c_adap, .addr = i2c_addr };
+       unsigned char buffer[7] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+       int rc;
+
+       if ((rc = tuner_i2c_xfer_recv(&i2c, buffer, 7))< 5) {
+               printk(KERN_WARNING "It is not a TEA5767. Received %i bytes.\n", rc);
+               return -EINVAL;
+       }
+
+       /* 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] &&
+           buffer[0] == buffer[3] && buffer[0] == buffer[4]) {
+               printk(KERN_WARNING "All bytes are equal. It is not a TEA5767\n");
+               return -EINVAL;
+       }
+
+       /*  Status bytes:
+        *  Byte 4: bit 3:1 : CI (Chip Identification) == 0
+        *          bit 0   : internally set to 0
+        *  Byte 5: bit 7:0 : == 0
+        */
+       if (((buffer[3] & 0x0f) != 0x00) || (buffer[4] != 0x00)) {
+               printk(KERN_WARNING "Chip ID is not zero. It is not a TEA5767\n");
+               return -EINVAL;
+       }
+
+
+       return 0;
+}
+
+static int tea5767_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+
+       return 0;
+}
+
+static int tea5767_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct tea5767_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+
+       return 0;
+}
+
+static int tea5767_set_config (struct dvb_frontend *fe, void *priv_cfg)
+{
+       struct tea5767_priv *priv = fe->tuner_priv;
+
+       memcpy(&priv->ctrl, priv_cfg, sizeof(priv->ctrl));
+
+       return 0;
+}
+
+static struct dvb_tuner_ops tea5767_tuner_ops = {
+       .info = {
+               .name           = "tea5767", // Philips TEA5767HN FM Radio
+       },
+
+       .set_analog_params = set_radio_freq,
+       .set_config        = tea5767_set_config,
+       .sleep             = tea5767_standby,
+       .release           = tea5767_release,
+       .get_frequency     = tea5767_get_frequency,
+       .get_status        = tea5767_get_status,
+       .get_rf_strength   = tea5767_get_rf_strength,
+};
+
+struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe,
+                                   struct i2c_adapter* i2c_adap,
+                                   u8 i2c_addr)
+{
+       struct tea5767_priv *priv = NULL;
+
+       priv = kzalloc(sizeof(struct tea5767_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+       fe->tuner_priv = priv;
+
+       priv->i2c_props.addr  = i2c_addr;
+       priv->i2c_props.adap  = i2c_adap;
+       priv->i2c_props.name  = "tea5767";
+
+       priv->ctrl.xtal_freq  = TEA5767_HIGH_LO_32768;
+       priv->ctrl.port1      = 1;
+       priv->ctrl.port2      = 1;
+       priv->ctrl.high_cut   = 1;
+       priv->ctrl.st_noise   = 1;
+       priv->ctrl.japan_band = 1;
+
+       memcpy(&fe->ops.tuner_ops, &tea5767_tuner_ops,
+              sizeof(struct dvb_tuner_ops));
+
+       tuner_info("type set to %s\n", "Philips TEA5767HN FM Radio");
+
+       return fe;
+}
+
+EXPORT_SYMBOL_GPL(tea5767_attach);
+EXPORT_SYMBOL_GPL(tea5767_autodetection);
+
+MODULE_DESCRIPTION("Philips TEA5767 FM tuner driver");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/tea5767.h b/drivers/media/tuners/tea5767.h
new file mode 100644 (file)
index 0000000..d30ab1b
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+    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 __TEA5767_H__
+#define __TEA5767_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+enum tea5767_xtal {
+       TEA5767_LOW_LO_32768    = 0,
+       TEA5767_HIGH_LO_32768   = 1,
+       TEA5767_LOW_LO_13MHz    = 2,
+       TEA5767_HIGH_LO_13MHz   = 3,
+};
+
+struct tea5767_ctrl {
+       unsigned int            port1:1;
+       unsigned int            port2:1;
+       unsigned int            high_cut:1;
+       unsigned int            st_noise:1;
+       unsigned int            soft_mute:1;
+       unsigned int            japan_band:1;
+       unsigned int            deemph_75:1;
+       unsigned int            pllref:1;
+       enum tea5767_xtal       xtal_freq;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_TEA5767) || (defined(CONFIG_MEDIA_TUNER_TEA5767_MODULE) && defined(MODULE))
+extern int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr);
+
+extern struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe,
+                                          struct i2c_adapter* i2c_adap,
+                                          u8 i2c_addr);
+#else
+static inline int tea5767_autodetection(struct i2c_adapter* i2c_adap,
+                                       u8 i2c_addr)
+{
+       printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
+              __func__);
+       return -EINVAL;
+}
+
+static inline struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe,
+                                                  struct i2c_adapter* i2c_adap,
+                                                  u8 i2c_addr)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* __TEA5767_H__ */
diff --git a/drivers/media/tuners/tua9001.c b/drivers/media/tuners/tua9001.c
new file mode 100644 (file)
index 0000000..de26070
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Infineon TUA 9001 silicon tuner driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "tua9001.h"
+#include "tua9001_priv.h"
+
+/* write register */
+static int tua9001_wr_reg(struct tua9001_priv *priv, u8 reg, u16 val)
+{
+       int ret;
+       u8 buf[3] = { reg, (val >> 8) & 0xff, (val >> 0) & 0xff };
+       struct i2c_msg msg[1] = {
+               {
+                       .addr = priv->cfg->i2c_addr,
+                       .flags = 0,
+                       .len = sizeof(buf),
+                       .buf = buf,
+               }
+       };
+
+       ret = i2c_transfer(priv->i2c, msg, 1);
+       if (ret == 1) {
+               ret = 0;
+       } else {
+               printk(KERN_WARNING "%s: I2C wr failed=%d reg=%02x\n",
+                               __func__, ret, reg);
+               ret = -EREMOTEIO;
+       }
+
+       return ret;
+}
+
+static int tua9001_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+
+       return 0;
+}
+
+static int tua9001_init(struct dvb_frontend *fe)
+{
+       struct tua9001_priv *priv = fe->tuner_priv;
+       int ret = 0;
+       u8 i;
+       struct reg_val data[] = {
+               { 0x1e, 0x6512 },
+               { 0x25, 0xb888 },
+               { 0x39, 0x5460 },
+               { 0x3b, 0x00c0 },
+               { 0x3a, 0xf000 },
+               { 0x08, 0x0000 },
+               { 0x32, 0x0030 },
+               { 0x41, 0x703a },
+               { 0x40, 0x1c78 },
+               { 0x2c, 0x1c00 },
+               { 0x36, 0xc013 },
+               { 0x37, 0x6f18 },
+               { 0x27, 0x0008 },
+               { 0x2a, 0x0001 },
+               { 0x34, 0x0a40 },
+       };
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c-gate */
+
+       for (i = 0; i < ARRAY_SIZE(data); i++) {
+               ret = tua9001_wr_reg(priv, data[i].reg, data[i].val);
+               if (ret)
+                       break;
+       }
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c-gate */
+
+       if (ret < 0)
+               pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int tua9001_set_params(struct dvb_frontend *fe)
+{
+       struct tua9001_priv *priv = fe->tuner_priv;
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       int ret, i;
+       u16 val;
+       u32 frequency;
+       struct reg_val data[2];
+
+       pr_debug("%s: delivery_system=%d frequency=%d bandwidth_hz=%d\n",
+                       __func__, c->delivery_system, c->frequency,
+                       c->bandwidth_hz);
+
+       switch (c->delivery_system) {
+       case SYS_DVBT:
+               switch (c->bandwidth_hz) {
+               case 8000000:
+                       val  = 0x0000;
+                       break;
+               case 7000000:
+                       val  = 0x1000;
+                       break;
+               case 6000000:
+                       val  = 0x2000;
+                       break;
+               case 5000000:
+                       val  = 0x3000;
+                       break;
+               default:
+                       ret = -EINVAL;
+                       goto err;
+               }
+               break;
+       default:
+               ret = -EINVAL;
+               goto err;
+       }
+
+       data[0].reg = 0x04;
+       data[0].val = val;
+
+       frequency = (c->frequency - 150000000);
+       frequency /= 100;
+       frequency *= 48;
+       frequency /= 10000;
+
+       data[1].reg = 0x1f;
+       data[1].val = frequency;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c-gate */
+
+       for (i = 0; i < ARRAY_SIZE(data); i++) {
+               ret = tua9001_wr_reg(priv, data[i].reg, data[i].val);
+               if (ret < 0)
+                       break;
+       }
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c-gate */
+
+err:
+       if (ret < 0)
+               pr_debug("%s: failed=%d\n", __func__, ret);
+
+       return ret;
+}
+
+static int tua9001_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       *frequency = 0; /* Zero-IF */
+
+       return 0;
+}
+
+static const struct dvb_tuner_ops tua9001_tuner_ops = {
+       .info = {
+               .name           = "Infineon TUA 9001",
+
+               .frequency_min  = 170000000,
+               .frequency_max  = 862000000,
+               .frequency_step = 0,
+       },
+
+       .release = tua9001_release,
+
+       .init = tua9001_init,
+       .set_params = tua9001_set_params,
+
+       .get_if_frequency = tua9001_get_if_frequency,
+};
+
+struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe,
+               struct i2c_adapter *i2c, struct tua9001_config *cfg)
+{
+       struct tua9001_priv *priv = NULL;
+
+       priv = kzalloc(sizeof(struct tua9001_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->cfg = cfg;
+       priv->i2c = i2c;
+
+       printk(KERN_INFO "Infineon TUA 9001 successfully attached.");
+
+       memcpy(&fe->ops.tuner_ops, &tua9001_tuner_ops,
+                       sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = priv;
+       return fe;
+}
+EXPORT_SYMBOL(tua9001_attach);
+
+MODULE_DESCRIPTION("Infineon TUA 9001 silicon tuner driver");
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/tua9001.h b/drivers/media/tuners/tua9001.h
new file mode 100644 (file)
index 0000000..38d6ae7
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Infineon TUA 9001 silicon tuner driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef TUA9001_H
+#define TUA9001_H
+
+#include "dvb_frontend.h"
+
+struct tua9001_config {
+       /*
+        * I2C address
+        */
+       u8 i2c_addr;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_TUA9001) || \
+       (defined(CONFIG_MEDIA_TUNER_TUA9001_MODULE) && defined(MODULE))
+extern struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe,
+               struct i2c_adapter *i2c, struct tua9001_config *cfg);
+#else
+static inline struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe,
+               struct i2c_adapter *i2c, struct tua9001_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/tuners/tua9001_priv.h b/drivers/media/tuners/tua9001_priv.h
new file mode 100644 (file)
index 0000000..73cc1ce
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Infineon TUA 9001 silicon tuner driver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ *    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.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef TUA9001_PRIV_H
+#define TUA9001_PRIV_H
+
+struct reg_val {
+       u8 reg;
+       u16 val;
+};
+
+struct tua9001_priv {
+       struct tua9001_config *cfg;
+       struct i2c_adapter *i2c;
+};
+
+#endif
diff --git a/drivers/media/tuners/tuner-i2c.h b/drivers/media/tuners/tuner-i2c.h
new file mode 100644 (file)
index 0000000..18f0056
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+    tuner-i2c.h - i2c interface for different tuners
+
+    Copyright (C) 2007 Michael Krufky (mkrufky@linuxtv.org)
+
+    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 __TUNER_I2C_H__
+#define __TUNER_I2C_H__
+
+#include <linux/i2c.h>
+#include <linux/slab.h>
+
+struct tuner_i2c_props {
+       u8 addr;
+       struct i2c_adapter *adap;
+
+       /* used for tuner instance management */
+       int count;
+       char *name;
+};
+
+static inline int tuner_i2c_xfer_send(struct tuner_i2c_props *props, char *buf, int len)
+{
+       struct i2c_msg msg = { .addr = props->addr, .flags = 0,
+                              .buf = buf, .len = len };
+       int ret = i2c_transfer(props->adap, &msg, 1);
+
+       return (ret == 1) ? len : ret;
+}
+
+static inline int tuner_i2c_xfer_recv(struct tuner_i2c_props *props, char *buf, int len)
+{
+       struct i2c_msg msg = { .addr = props->addr, .flags = I2C_M_RD,
+                              .buf = buf, .len = len };
+       int ret = i2c_transfer(props->adap, &msg, 1);
+
+       return (ret == 1) ? len : ret;
+}
+
+static inline int tuner_i2c_xfer_send_recv(struct tuner_i2c_props *props,
+                                          char *obuf, int olen,
+                                          char *ibuf, int ilen)
+{
+       struct i2c_msg msg[2] = { { .addr = props->addr, .flags = 0,
+                                   .buf = obuf, .len = olen },
+                                 { .addr = props->addr, .flags = I2C_M_RD,
+                                   .buf = ibuf, .len = ilen } };
+       int ret = i2c_transfer(props->adap, msg, 2);
+
+       return (ret == 2) ? ilen : ret;
+}
+
+/* Callers must declare as a global for the module:
+ *
+ * static LIST_HEAD(hybrid_tuner_instance_list);
+ *
+ * hybrid_tuner_instance_list should be the third argument
+ * passed into hybrid_tuner_request_state().
+ *
+ * state structure must contain the following:
+ *
+ *     struct list_head        hybrid_tuner_instance_list;
+ *     struct tuner_i2c_props  i2c_props;
+ *
+ * hybrid_tuner_instance_list (both within state structure and globally)
+ * is only required if the driver is using hybrid_tuner_request_state
+ * and hybrid_tuner_release_state to manage state sharing between
+ * multiple instances of hybrid tuners.
+ */
+
+#define tuner_printk(kernlvl, i2cprops, fmt, arg...) do {              \
+       printk(kernlvl "%s %d-%04x: " fmt, i2cprops.name,               \
+                       i2cprops.adap ?                                 \
+                               i2c_adapter_id(i2cprops.adap) : -1,     \
+                       i2cprops.addr, ##arg);                          \
+        } while (0)
+
+/* TO DO: convert all callers of these macros to pass in
+ * struct tuner_i2c_props, then remove the macro wrappers */
+
+#define __tuner_warn(i2cprops, fmt, arg...) do {                       \
+       tuner_printk(KERN_WARNING, i2cprops, fmt, ##arg);               \
+       } while (0)
+
+#define __tuner_info(i2cprops, fmt, arg...) do {                       \
+       tuner_printk(KERN_INFO, i2cprops, fmt, ##arg);                  \
+       } while (0)
+
+#define __tuner_err(i2cprops, fmt, arg...) do {                                \
+       tuner_printk(KERN_ERR, i2cprops, fmt, ##arg);                   \
+       } while (0)
+
+#define __tuner_dbg(i2cprops, fmt, arg...) do {                                \
+       if ((debug))                                                    \
+               tuner_printk(KERN_DEBUG, i2cprops, fmt, ##arg);         \
+       } while (0)
+
+#define tuner_warn(fmt, arg...) __tuner_warn(priv->i2c_props, fmt, ##arg)
+#define tuner_info(fmt, arg...) __tuner_info(priv->i2c_props, fmt, ##arg)
+#define tuner_err(fmt, arg...) __tuner_err(priv->i2c_props, fmt, ##arg)
+#define tuner_dbg(fmt, arg...) __tuner_dbg(priv->i2c_props, fmt, ##arg)
+
+/****************************************************************************/
+
+/* The return value of hybrid_tuner_request_state indicates the number of
+ * instances using this tuner object.
+ *
+ * 0 - no instances, indicates an error - kzalloc must have failed
+ *
+ * 1 - one instance, indicates that the tuner object was created successfully
+ *
+ * 2 (or more) instances, indicates that an existing tuner object was found
+ */
+
+#define hybrid_tuner_request_state(type, state, list, i2cadap, i2caddr, devname)\
+({                                                                     \
+       int __ret = 0;                                                  \
+       list_for_each_entry(state, &list, hybrid_tuner_instance_list) { \
+               if (((i2cadap) && (state->i2c_props.adap)) &&           \
+                   ((i2c_adapter_id(state->i2c_props.adap) ==          \
+                     i2c_adapter_id(i2cadap)) &&                       \
+                    (i2caddr == state->i2c_props.addr))) {             \
+                       __tuner_info(state->i2c_props,                  \
+                                    "attaching existing instance\n");  \
+                       state->i2c_props.count++;                       \
+                       __ret = state->i2c_props.count;                 \
+                       break;                                          \
+               }                                                       \
+       }                                                               \
+       if (0 == __ret) {                                               \
+               state = kzalloc(sizeof(type), GFP_KERNEL);              \
+               if (NULL == state)                                      \
+                       goto __fail;                                    \
+               state->i2c_props.addr = i2caddr;                        \
+               state->i2c_props.adap = i2cadap;                        \
+               state->i2c_props.name = devname;                        \
+               __tuner_info(state->i2c_props,                          \
+                            "creating new instance\n");                \
+               list_add_tail(&state->hybrid_tuner_instance_list, &list);\
+               state->i2c_props.count++;                               \
+               __ret = state->i2c_props.count;                         \
+       }                                                               \
+__fail:                                                                        \
+       __ret;                                                          \
+})
+
+#define hybrid_tuner_release_state(state)                              \
+({                                                                     \
+       int __ret;                                                      \
+       state->i2c_props.count--;                                       \
+       __ret = state->i2c_props.count;                                 \
+       if (!state->i2c_props.count) {                                  \
+               __tuner_info(state->i2c_props, "destroying instance\n");\
+               list_del(&state->hybrid_tuner_instance_list);           \
+               kfree(state);                                           \
+       }                                                               \
+       __ret;                                                          \
+})
+
+#define hybrid_tuner_report_instance_count(state)                      \
+({                                                                     \
+       int __ret = 0;                                                  \
+       if (state)                                                      \
+               __ret = state->i2c_props.count;                         \
+       __ret;                                                          \
+})
+
+#endif /* __TUNER_I2C_H__ */
diff --git a/drivers/media/tuners/tuner-simple.c b/drivers/media/tuners/tuner-simple.c
new file mode 100644 (file)
index 0000000..39e7e58
--- /dev/null
@@ -0,0 +1,1155 @@
+/*
+ * i2c tv tuner chip device driver
+ * controls all those simple 4-control-bytes style tuners.
+ *
+ * This "tuner-simple" module was split apart from the original "tuner" module.
+ */
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <media/tuner.h>
+#include <media/v4l2-common.h>
+#include <media/tuner-types.h>
+#include "tuner-i2c.h"
+#include "tuner-simple.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable verbose debug messages");
+
+#define TUNER_SIMPLE_MAX 64
+static unsigned int simple_devcount;
+
+static int offset;
+module_param(offset, int, 0664);
+MODULE_PARM_DESC(offset, "Allows to specify an offset for tuner");
+
+static unsigned int atv_input[TUNER_SIMPLE_MAX] = \
+                       { [0 ... (TUNER_SIMPLE_MAX-1)] = 0 };
+static unsigned int dtv_input[TUNER_SIMPLE_MAX] = \
+                       { [0 ... (TUNER_SIMPLE_MAX-1)] = 0 };
+module_param_array(atv_input, int, NULL, 0644);
+module_param_array(dtv_input, int, NULL, 0644);
+MODULE_PARM_DESC(atv_input, "specify atv rf input, 0 for autoselect");
+MODULE_PARM_DESC(dtv_input, "specify dtv rf input, 0 for autoselect");
+
+/* ---------------------------------------------------------------------- */
+
+/* tv standard selection for Temic 4046 FM5
+   this value takes the low bits of control byte 2
+   from datasheet Rev.01, Feb.00
+     standard     BG      I       L       L2      D
+     picture IF   38.9    38.9    38.9    33.95   38.9
+     sound 1      33.4    32.9    32.4    40.45   32.4
+     sound 2      33.16
+     NICAM        33.05   32.348  33.05           33.05
+ */
+#define TEMIC_SET_PAL_I         0x05
+#define TEMIC_SET_PAL_DK        0x09
+#define TEMIC_SET_PAL_L         0x0a /* SECAM ? */
+#define TEMIC_SET_PAL_L2        0x0b /* change IF ! */
+#define TEMIC_SET_PAL_BG        0x0c
+
+/* tv tuner system standard selection for Philips FQ1216ME
+   this value takes the low bits of control byte 2
+   from datasheet "1999 Nov 16" (supersedes "1999 Mar 23")
+     standard          BG      DK      I       L       L`
+     picture carrier   38.90   38.90   38.90   38.90   33.95
+     colour            34.47   34.47   34.47   34.47   38.38
+     sound 1           33.40   32.40   32.90   32.40   40.45
+     sound 2           33.16   -       -       -       -
+     NICAM             33.05   33.05   32.35   33.05   39.80
+ */
+#define PHILIPS_SET_PAL_I      0x01 /* Bit 2 always zero !*/
+#define PHILIPS_SET_PAL_BGDK   0x09
+#define PHILIPS_SET_PAL_L2     0x0a
+#define PHILIPS_SET_PAL_L      0x0b
+
+/* system switching for Philips FI1216MF MK2
+   from datasheet "1996 Jul 09",
+    standard         BG     L      L'
+    picture carrier  38.90  38.90  33.95
+    colour          34.47  34.37  38.38
+    sound 1          33.40  32.40  40.45
+    sound 2          33.16  -      -
+    NICAM            33.05  33.05  39.80
+ */
+#define PHILIPS_MF_SET_STD_BG  0x01 /* Bit 2 must be zero, Bit 3 is system output */
+#define PHILIPS_MF_SET_STD_L   0x03 /* Used on Secam France */
+#define PHILIPS_MF_SET_STD_LC  0x02 /* Used on SECAM L' */
+
+/* Control byte */
+
+#define TUNER_RATIO_MASK        0x06 /* Bit cb1:cb2 */
+#define TUNER_RATIO_SELECT_50   0x00
+#define TUNER_RATIO_SELECT_32   0x02
+#define TUNER_RATIO_SELECT_166  0x04
+#define TUNER_RATIO_SELECT_62   0x06
+
+#define TUNER_CHARGE_PUMP       0x40  /* Bit cb6 */
+
+/* Status byte */
+
+#define TUNER_POR        0x80
+#define TUNER_FL          0x40
+#define TUNER_MODE        0x38
+#define TUNER_AFC         0x07
+#define TUNER_SIGNAL      0x07
+#define TUNER_STEREO      0x10
+
+#define TUNER_PLL_LOCKED   0x40
+#define TUNER_STEREO_MK3   0x04
+
+static DEFINE_MUTEX(tuner_simple_list_mutex);
+static LIST_HEAD(hybrid_tuner_instance_list);
+
+struct tuner_simple_priv {
+       unsigned int nr;
+       u16 last_div;
+
+       struct tuner_i2c_props i2c_props;
+       struct list_head hybrid_tuner_instance_list;
+
+       unsigned int type;
+       struct tunertype *tun;
+
+       u32 frequency;
+       u32 bandwidth;
+};
+
+/* ---------------------------------------------------------------------- */
+
+static int tuner_read_status(struct dvb_frontend *fe)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       unsigned char byte;
+
+       if (1 != tuner_i2c_xfer_recv(&priv->i2c_props, &byte, 1))
+               return 0;
+
+       return byte;
+}
+
+static inline int tuner_signal(const int status)
+{
+       return (status & TUNER_SIGNAL) << 13;
+}
+
+static inline int tuner_stereo(const int type, const int status)
+{
+       switch (type) {
+       case TUNER_PHILIPS_FM1216ME_MK3:
+       case TUNER_PHILIPS_FM1236_MK3:
+       case TUNER_PHILIPS_FM1256_IH3:
+       case TUNER_LG_NTSC_TAPE:
+       case TUNER_TCL_MF02GIP_5N:
+               return ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
+       case TUNER_PHILIPS_FM1216MK5:
+               return status | TUNER_STEREO;
+       default:
+               return status & TUNER_STEREO;
+       }
+}
+
+static inline int tuner_islocked(const int status)
+{
+       return (status & TUNER_FL);
+}
+
+static inline int tuner_afcstatus(const int status)
+{
+       return (status & TUNER_AFC) - 2;
+}
+
+
+static int simple_get_status(struct dvb_frontend *fe, u32 *status)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       int tuner_status;
+
+       if (priv->i2c_props.adap == NULL)
+               return -EINVAL;
+
+       tuner_status = tuner_read_status(fe);
+
+       *status = 0;
+
+       if (tuner_islocked(tuner_status))
+               *status = TUNER_STATUS_LOCKED;
+       if (tuner_stereo(priv->type, tuner_status))
+               *status |= TUNER_STATUS_STEREO;
+
+       tuner_dbg("AFC Status: %d\n", tuner_afcstatus(tuner_status));
+
+       return 0;
+}
+
+static int simple_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       int signal;
+
+       if (priv->i2c_props.adap == NULL)
+               return -EINVAL;
+
+       signal = tuner_signal(tuner_read_status(fe));
+
+       *strength = signal;
+
+       tuner_dbg("Signal strength: %d\n", signal);
+
+       return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static inline char *tuner_param_name(enum param_type type)
+{
+       char *name;
+
+       switch (type) {
+       case TUNER_PARAM_TYPE_RADIO:
+               name = "radio";
+               break;
+       case TUNER_PARAM_TYPE_PAL:
+               name = "pal";
+               break;
+       case TUNER_PARAM_TYPE_SECAM:
+               name = "secam";
+               break;
+       case TUNER_PARAM_TYPE_NTSC:
+               name = "ntsc";
+               break;
+       case TUNER_PARAM_TYPE_DIGITAL:
+               name = "digital";
+               break;
+       default:
+               name = "unknown";
+               break;
+       }
+       return name;
+}
+
+static struct tuner_params *simple_tuner_params(struct dvb_frontend *fe,
+                                               enum param_type desired_type)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       struct tunertype *tun = priv->tun;
+       int i;
+
+       for (i = 0; i < tun->count; i++)
+               if (desired_type == tun->params[i].type)
+                       break;
+
+       /* use default tuner params if desired_type not available */
+       if (i == tun->count) {
+               tuner_dbg("desired params (%s) undefined for tuner %d\n",
+                         tuner_param_name(desired_type), priv->type);
+               i = 0;
+       }
+
+       tuner_dbg("using tuner params #%d (%s)\n", i,
+                 tuner_param_name(tun->params[i].type));
+
+       return &tun->params[i];
+}
+
+static int simple_config_lookup(struct dvb_frontend *fe,
+                               struct tuner_params *t_params,
+                               unsigned *frequency, u8 *config, u8 *cb)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       int i;
+
+       for (i = 0; i < t_params->count; i++) {
+               if (*frequency > t_params->ranges[i].limit)
+                       continue;
+               break;
+       }
+       if (i == t_params->count) {
+               tuner_dbg("frequency out of range (%d > %d)\n",
+                         *frequency, t_params->ranges[i - 1].limit);
+               *frequency = t_params->ranges[--i].limit;
+       }
+       *config = t_params->ranges[i].config;
+       *cb     = t_params->ranges[i].cb;
+
+       tuner_dbg("freq = %d.%02d (%d), range = %d, "
+                 "config = 0x%02x, cb = 0x%02x\n",
+                 *frequency / 16, *frequency % 16 * 100 / 16, *frequency,
+                 i, *config, *cb);
+
+       return i;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void simple_set_rf_input(struct dvb_frontend *fe,
+                               u8 *config, u8 *cb, unsigned int rf)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+
+       switch (priv->type) {
+       case TUNER_PHILIPS_TUV1236D:
+               switch (rf) {
+               case 1:
+                       *cb |= 0x08;
+                       break;
+               default:
+                       *cb &= ~0x08;
+                       break;
+               }
+               break;
+       case TUNER_PHILIPS_FCV1236D:
+               switch (rf) {
+               case 1:
+                       *cb |= 0x01;
+                       break;
+               default:
+                       *cb &= ~0x01;
+                       break;
+               }
+               break;
+       default:
+               break;
+       }
+}
+
+static int simple_std_setup(struct dvb_frontend *fe,
+                           struct analog_parameters *params,
+                           u8 *config, u8 *cb)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       int rc;
+
+       /* tv norm specific stuff for multi-norm tuners */
+       switch (priv->type) {
+       case TUNER_PHILIPS_SECAM: /* FI1216MF */
+               /* 0x01 -> ??? no change ??? */
+               /* 0x02 -> PAL BDGHI / SECAM L */
+               /* 0x04 -> ??? PAL others / SECAM others ??? */
+               *cb &= ~0x03;
+               if (params->std & V4L2_STD_SECAM_L)
+                       /* also valid for V4L2_STD_SECAM */
+                       *cb |= PHILIPS_MF_SET_STD_L;
+               else if (params->std & V4L2_STD_SECAM_LC)
+                       *cb |= PHILIPS_MF_SET_STD_LC;
+               else /* V4L2_STD_B|V4L2_STD_GH */
+                       *cb |= PHILIPS_MF_SET_STD_BG;
+               break;
+
+       case TUNER_TEMIC_4046FM5:
+               *cb &= ~0x0f;
+
+               if (params->std & V4L2_STD_PAL_BG) {
+                       *cb |= TEMIC_SET_PAL_BG;
+
+               } else if (params->std & V4L2_STD_PAL_I) {
+                       *cb |= TEMIC_SET_PAL_I;
+
+               } else if (params->std & V4L2_STD_PAL_DK) {
+                       *cb |= TEMIC_SET_PAL_DK;
+
+               } else if (params->std & V4L2_STD_SECAM_L) {
+                       *cb |= TEMIC_SET_PAL_L;
+
+               }
+               break;
+
+       case TUNER_PHILIPS_FQ1216ME:
+               *cb &= ~0x0f;
+
+               if (params->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) {
+                       *cb |= PHILIPS_SET_PAL_BGDK;
+
+               } else if (params->std & V4L2_STD_PAL_I) {
+                       *cb |= PHILIPS_SET_PAL_I;
+
+               } else if (params->std & V4L2_STD_SECAM_L) {
+                       *cb |= PHILIPS_SET_PAL_L;
+
+               }
+               break;
+
+       case TUNER_PHILIPS_FCV1236D:
+               /* 0x00 -> ATSC antenna input 1 */
+               /* 0x01 -> ATSC antenna input 2 */
+               /* 0x02 -> NTSC antenna input 1 */
+               /* 0x03 -> NTSC antenna input 2 */
+               *cb &= ~0x03;
+               if (!(params->std & V4L2_STD_ATSC))
+                       *cb |= 2;
+               break;
+
+       case TUNER_MICROTUNE_4042FI5:
+               /* Set the charge pump for fast tuning */
+               *config |= TUNER_CHARGE_PUMP;
+               break;
+
+       case TUNER_PHILIPS_TUV1236D:
+       {
+               struct tuner_i2c_props i2c = priv->i2c_props;
+               /* 0x40 -> ATSC antenna input 1 */
+               /* 0x48 -> ATSC antenna input 2 */
+               /* 0x00 -> NTSC antenna input 1 */
+               /* 0x08 -> NTSC antenna input 2 */
+               u8 buffer[4] = { 0x14, 0x00, 0x17, 0x00};
+               *cb &= ~0x40;
+               if (params->std & V4L2_STD_ATSC) {
+                       *cb |= 0x40;
+                       buffer[1] = 0x04;
+               }
+               /* set to the correct mode (analog or digital) */
+               i2c.addr = 0x0a;
+               rc = tuner_i2c_xfer_send(&i2c, &buffer[0], 2);
+               if (2 != rc)
+                       tuner_warn("i2c i/o error: rc == %d "
+                                  "(should be 2)\n", rc);
+               rc = tuner_i2c_xfer_send(&i2c, &buffer[2], 2);
+               if (2 != rc)
+                       tuner_warn("i2c i/o error: rc == %d "
+                                  "(should be 2)\n", rc);
+               break;
+       }
+       }
+       if (atv_input[priv->nr])
+               simple_set_rf_input(fe, config, cb, atv_input[priv->nr]);
+
+       return 0;
+}
+
+static int simple_set_aux_byte(struct dvb_frontend *fe, u8 config, u8 aux)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       int rc;
+       u8 buffer[2];
+
+       buffer[0] = (config & ~0x38) | 0x18;
+       buffer[1] = aux;
+
+       tuner_dbg("setting aux byte: 0x%02x 0x%02x\n", buffer[0], buffer[1]);
+
+       rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2);
+       if (2 != rc)
+               tuner_warn("i2c i/o error: rc == %d (should be 2)\n", rc);
+
+       return rc == 2 ? 0 : rc;
+}
+
+static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer,
+                           u16 div, u8 config, u8 cb)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       int rc;
+
+       switch (priv->type) {
+       case TUNER_LG_TDVS_H06XF:
+               simple_set_aux_byte(fe, config, 0x20);
+               break;
+       case TUNER_PHILIPS_FQ1216LME_MK3:
+               simple_set_aux_byte(fe, config, 0x60); /* External AGC */
+               break;
+       case TUNER_MICROTUNE_4042FI5:
+       {
+               /* FIXME - this may also work for other tuners */
+               unsigned long timeout = jiffies + msecs_to_jiffies(1);
+               u8 status_byte = 0;
+
+               /* Wait until the PLL locks */
+               for (;;) {
+                       if (time_after(jiffies, timeout))
+                               return 0;
+                       rc = tuner_i2c_xfer_recv(&priv->i2c_props,
+                                                &status_byte, 1);
+                       if (1 != rc) {
+                               tuner_warn("i2c i/o read error: rc == %d "
+                                          "(should be 1)\n", rc);
+                               break;
+                       }
+                       if (status_byte & TUNER_PLL_LOCKED)
+                               break;
+                       udelay(10);
+               }
+
+               /* Set the charge pump for optimized phase noise figure */
+               config &= ~TUNER_CHARGE_PUMP;
+               buffer[0] = (div>>8) & 0x7f;
+               buffer[1] = div      & 0xff;
+               buffer[2] = config;
+               buffer[3] = cb;
+               tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
+                         buffer[0], buffer[1], buffer[2], buffer[3]);
+
+               rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4);
+               if (4 != rc)
+                       tuner_warn("i2c i/o error: rc == %d "
+                                  "(should be 4)\n", rc);
+               break;
+       }
+       }
+
+       return 0;
+}
+
+static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+
+       switch (priv->type) {
+       case TUNER_TENA_9533_DI:
+       case TUNER_YMEC_TVF_5533MF:
+               tuner_dbg("This tuner doesn't have FM. "
+                         "Most cards have a TEA5767 for FM\n");
+               return 0;
+       case TUNER_PHILIPS_FM1216ME_MK3:
+       case TUNER_PHILIPS_FM1236_MK3:
+       case TUNER_PHILIPS_FMD1216ME_MK3:
+       case TUNER_PHILIPS_FMD1216MEX_MK3:
+       case TUNER_LG_NTSC_TAPE:
+       case TUNER_PHILIPS_FM1256_IH3:
+       case TUNER_TCL_MF02GIP_5N:
+               buffer[3] = 0x19;
+               break;
+       case TUNER_PHILIPS_FM1216MK5:
+               buffer[2] = 0x88;
+               buffer[3] = 0x09;
+               break;
+       case TUNER_TNF_5335MF:
+               buffer[3] = 0x11;
+               break;
+       case TUNER_LG_PAL_FM:
+               buffer[3] = 0xa5;
+               break;
+       case TUNER_THOMSON_DTT761X:
+               buffer[3] = 0x39;
+               break;
+       case TUNER_PHILIPS_FQ1216LME_MK3:
+       case TUNER_PHILIPS_FQ1236_MK5:
+               tuner_err("This tuner doesn't have FM\n");
+               /* Set the low band for sanity, since it covers 88-108 MHz */
+               buffer[3] = 0x01;
+               break;
+       case TUNER_MICROTUNE_4049FM5:
+       default:
+               buffer[3] = 0xa4;
+               break;
+       }
+
+       return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int simple_set_tv_freq(struct dvb_frontend *fe,
+                             struct analog_parameters *params)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       u8 config, cb;
+       u16 div;
+       u8 buffer[4];
+       int rc, IFPCoff, i;
+       enum param_type desired_type;
+       struct tuner_params *t_params;
+
+       /* IFPCoff = Video Intermediate Frequency - Vif:
+               940  =16*58.75  NTSC/J (Japan)
+               732  =16*45.75  M/N STD
+               704  =16*44     ATSC (at DVB code)
+               632  =16*39.50  I U.K.
+               622.4=16*38.90  B/G D/K I, L STD
+               592  =16*37.00  D China
+               590  =16.36.875 B Australia
+               543.2=16*33.95  L' STD
+               171.2=16*10.70  FM Radio (at set_radio_freq)
+       */
+
+       if (params->std == V4L2_STD_NTSC_M_JP) {
+               IFPCoff      = 940;
+               desired_type = TUNER_PARAM_TYPE_NTSC;
+       } else if ((params->std & V4L2_STD_MN) &&
+                 !(params->std & ~V4L2_STD_MN)) {
+               IFPCoff      = 732;
+               desired_type = TUNER_PARAM_TYPE_NTSC;
+       } else if (params->std == V4L2_STD_SECAM_LC) {
+               IFPCoff      = 543;
+               desired_type = TUNER_PARAM_TYPE_SECAM;
+       } else {
+               IFPCoff      = 623;
+               desired_type = TUNER_PARAM_TYPE_PAL;
+       }
+
+       t_params = simple_tuner_params(fe, desired_type);
+
+       i = simple_config_lookup(fe, t_params, &params->frequency,
+                                &config, &cb);
+
+       div = params->frequency + IFPCoff + offset;
+
+       tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, "
+                 "Offset=%d.%02d MHz, div=%0d\n",
+                 params->frequency / 16, params->frequency % 16 * 100 / 16,
+                 IFPCoff / 16, IFPCoff % 16 * 100 / 16,
+                 offset / 16, offset % 16 * 100 / 16, div);
+
+       /* tv norm specific stuff for multi-norm tuners */
+       simple_std_setup(fe, params, &config, &cb);
+
+       if (t_params->cb_first_if_lower_freq && div < priv->last_div) {
+               buffer[0] = config;
+               buffer[1] = cb;
+               buffer[2] = (div>>8) & 0x7f;
+               buffer[3] = div      & 0xff;
+       } else {
+               buffer[0] = (div>>8) & 0x7f;
+               buffer[1] = div      & 0xff;
+               buffer[2] = config;
+               buffer[3] = cb;
+       }
+       priv->last_div = div;
+       if (t_params->has_tda9887) {
+               struct v4l2_priv_tun_config tda9887_cfg;
+               int tda_config = 0;
+               int is_secam_l = (params->std & (V4L2_STD_SECAM_L |
+                                                V4L2_STD_SECAM_LC)) &&
+                       !(params->std & ~(V4L2_STD_SECAM_L |
+                                         V4L2_STD_SECAM_LC));
+
+               tda9887_cfg.tuner = TUNER_TDA9887;
+               tda9887_cfg.priv  = &tda_config;
+
+               if (params->std == V4L2_STD_SECAM_LC) {
+                       if (t_params->port1_active ^ t_params->port1_invert_for_secam_lc)
+                               tda_config |= TDA9887_PORT1_ACTIVE;
+                       if (t_params->port2_active ^ t_params->port2_invert_for_secam_lc)
+                               tda_config |= TDA9887_PORT2_ACTIVE;
+               } else {
+                       if (t_params->port1_active)
+                               tda_config |= TDA9887_PORT1_ACTIVE;
+                       if (t_params->port2_active)
+                               tda_config |= TDA9887_PORT2_ACTIVE;
+               }
+               if (t_params->intercarrier_mode)
+                       tda_config |= TDA9887_INTERCARRIER;
+               if (is_secam_l) {
+                       if (i == 0 && t_params->default_top_secam_low)
+                               tda_config |= TDA9887_TOP(t_params->default_top_secam_low);
+                       else if (i == 1 && t_params->default_top_secam_mid)
+                               tda_config |= TDA9887_TOP(t_params->default_top_secam_mid);
+                       else if (t_params->default_top_secam_high)
+                               tda_config |= TDA9887_TOP(t_params->default_top_secam_high);
+               } else {
+                       if (i == 0 && t_params->default_top_low)
+                               tda_config |= TDA9887_TOP(t_params->default_top_low);
+                       else if (i == 1 && t_params->default_top_mid)
+                               tda_config |= TDA9887_TOP(t_params->default_top_mid);
+                       else if (t_params->default_top_high)
+                               tda_config |= TDA9887_TOP(t_params->default_top_high);
+               }
+               if (t_params->default_pll_gating_18)
+                       tda_config |= TDA9887_GATING_18;
+               i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG,
+                                   &tda9887_cfg);
+       }
+       tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
+                 buffer[0], buffer[1], buffer[2], buffer[3]);
+
+       rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4);
+       if (4 != rc)
+               tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc);
+
+       simple_post_tune(fe, &buffer[0], div, config, cb);
+
+       return 0;
+}
+
+static int simple_set_radio_freq(struct dvb_frontend *fe,
+                                struct analog_parameters *params)
+{
+       struct tunertype *tun;
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       u8 buffer[4];
+       u16 div;
+       int rc, j;
+       struct tuner_params *t_params;
+       unsigned int freq = params->frequency;
+
+       tun = priv->tun;
+
+       for (j = tun->count-1; j > 0; j--)
+               if (tun->params[j].type == TUNER_PARAM_TYPE_RADIO)
+                       break;
+       /* default t_params (j=0) will be used if desired type wasn't found */
+       t_params = &tun->params[j];
+
+       /* Select Radio 1st IF used */
+       switch (t_params->radio_if) {
+       case 0: /* 10.7 MHz */
+               freq += (unsigned int)(10.7*16000);
+               break;
+       case 1: /* 33.3 MHz */
+               freq += (unsigned int)(33.3*16000);
+               break;
+       case 2: /* 41.3 MHz */
+               freq += (unsigned int)(41.3*16000);
+               break;
+       default:
+               tuner_warn("Unsupported radio_if value %d\n",
+                          t_params->radio_if);
+               return 0;
+       }
+
+       buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) |
+                   TUNER_RATIO_SELECT_50; /* 50 kHz step */
+
+       /* Bandswitch byte */
+       simple_radio_bandswitch(fe, &buffer[0]);
+
+       /* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps
+          freq * (1 Mhz / 16000 V4L steps) * (20 PLL steps / 1 MHz) =
+          freq * (1/800) */
+       div = (freq + 400) / 800;
+
+       if (t_params->cb_first_if_lower_freq && div < priv->last_div) {
+               buffer[0] = buffer[2];
+               buffer[1] = buffer[3];
+               buffer[2] = (div>>8) & 0x7f;
+               buffer[3] = div      & 0xff;
+       } else {
+               buffer[0] = (div>>8) & 0x7f;
+               buffer[1] = div      & 0xff;
+       }
+
+       tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n",
+              buffer[0], buffer[1], buffer[2], buffer[3]);
+       priv->last_div = div;
+
+       if (t_params->has_tda9887) {
+               int config = 0;
+               struct v4l2_priv_tun_config tda9887_cfg;
+
+               tda9887_cfg.tuner = TUNER_TDA9887;
+               tda9887_cfg.priv = &config;
+
+               if (t_params->port1_active &&
+                   !t_params->port1_fm_high_sensitivity)
+                       config |= TDA9887_PORT1_ACTIVE;
+               if (t_params->port2_active &&
+                   !t_params->port2_fm_high_sensitivity)
+                       config |= TDA9887_PORT2_ACTIVE;
+               if (t_params->intercarrier_mode)
+                       config |= TDA9887_INTERCARRIER;
+/*             if (t_params->port1_set_for_fm_mono)
+                       config &= ~TDA9887_PORT1_ACTIVE;*/
+               if (t_params->fm_gain_normal)
+                       config |= TDA9887_GAIN_NORMAL;
+               if (t_params->radio_if == 2)
+                       config |= TDA9887_RIF_41_3;
+               i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG,
+                                   &tda9887_cfg);
+       }
+       rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4);
+       if (4 != rc)
+               tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc);
+
+       /* Write AUX byte */
+       switch (priv->type) {
+       case TUNER_PHILIPS_FM1216ME_MK3:
+               buffer[2] = 0x98;
+               buffer[3] = 0x20; /* set TOP AGC */
+               rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4);
+               if (4 != rc)
+                       tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc);
+               break;
+       }
+
+       return 0;
+}
+
+static int simple_set_params(struct dvb_frontend *fe,
+                            struct analog_parameters *params)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       int ret = -EINVAL;
+
+       if (priv->i2c_props.adap == NULL)
+               return -EINVAL;
+
+       switch (params->mode) {
+       case V4L2_TUNER_RADIO:
+               ret = simple_set_radio_freq(fe, params);
+               priv->frequency = params->frequency * 125 / 2;
+               break;
+       case V4L2_TUNER_ANALOG_TV:
+       case V4L2_TUNER_DIGITAL_TV:
+               ret = simple_set_tv_freq(fe, params);
+               priv->frequency = params->frequency * 62500;
+               break;
+       }
+       priv->bandwidth = 0;
+
+       return ret;
+}
+
+static void simple_set_dvb(struct dvb_frontend *fe, u8 *buf,
+                          const u32 delsys,
+                          const u32 frequency,
+                          const u32 bandwidth)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+
+       switch (priv->type) {
+       case TUNER_PHILIPS_FMD1216ME_MK3:
+       case TUNER_PHILIPS_FMD1216MEX_MK3:
+               if (bandwidth == 8000000 &&
+                   frequency >= 158870000)
+                       buf[3] |= 0x08;
+               break;
+       case TUNER_PHILIPS_TD1316:
+               /* determine band */
+               buf[3] |= (frequency < 161000000) ? 1 :
+                         (frequency < 444000000) ? 2 : 4;
+
+               /* setup PLL filter */
+               if (bandwidth == 8000000)
+                       buf[3] |= 1 << 3;
+               break;
+       case TUNER_PHILIPS_TUV1236D:
+       case TUNER_PHILIPS_FCV1236D:
+       {
+               unsigned int new_rf;
+
+               if (dtv_input[priv->nr])
+                       new_rf = dtv_input[priv->nr];
+               else
+                       switch (delsys) {
+                       case SYS_DVBC_ANNEX_B:
+                               new_rf = 1;
+                               break;
+                       case SYS_ATSC:
+                       default:
+                               new_rf = 0;
+                               break;
+                       }
+               simple_set_rf_input(fe, &buf[2], &buf[3], new_rf);
+               break;
+       }
+       default:
+               break;
+       }
+}
+
+static u32 simple_dvb_configure(struct dvb_frontend *fe, u8 *buf,
+                               const u32 delsys,
+                               const u32 freq,
+                               const u32 bw)
+{
+       /* This function returns the tuned frequency on success, 0 on error */
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       struct tunertype *tun = priv->tun;
+       static struct tuner_params *t_params;
+       u8 config, cb;
+       u32 div;
+       int ret;
+       u32 frequency = freq / 62500;
+
+       if (!tun->stepsize) {
+               /* tuner-core was loaded before the digital tuner was
+                * configured and somehow picked the wrong tuner type */
+               tuner_err("attempt to treat tuner %d (%s) as digital tuner "
+                         "without stepsize defined.\n",
+                         priv->type, priv->tun->name);
+               return 0; /* failure */
+       }
+
+       t_params = simple_tuner_params(fe, TUNER_PARAM_TYPE_DIGITAL);
+       ret = simple_config_lookup(fe, t_params, &frequency, &config, &cb);
+       if (ret < 0)
+               return 0; /* failure */
+
+       div = ((frequency + t_params->iffreq) * 62500 + offset +
+              tun->stepsize/2) / tun->stepsize;
+
+       buf[0] = div >> 8;
+       buf[1] = div & 0xff;
+       buf[2] = config;
+       buf[3] = cb;
+
+       simple_set_dvb(fe, buf, delsys, freq, bw);
+
+       tuner_dbg("%s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n",
+                 tun->name, div, buf[0], buf[1], buf[2], buf[3]);
+
+       /* calculate the frequency we set it to */
+       return (div * tun->stepsize) - t_params->iffreq;
+}
+
+static int simple_dvb_calc_regs(struct dvb_frontend *fe,
+                               u8 *buf, int buf_len)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u32 delsys = c->delivery_system;
+       u32 bw = c->bandwidth_hz;
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       u32 frequency;
+
+       if (buf_len < 5)
+               return -EINVAL;
+
+       frequency = simple_dvb_configure(fe, buf+1, delsys, c->frequency, bw);
+       if (frequency == 0)
+               return -EINVAL;
+
+       buf[0] = priv->i2c_props.addr;
+
+       priv->frequency = frequency;
+       priv->bandwidth = c->bandwidth_hz;
+
+       return 5;
+}
+
+static int simple_dvb_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u32 delsys = c->delivery_system;
+       u32 bw = c->bandwidth_hz;
+       u32 freq = c->frequency;
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       u32 frequency;
+       u32 prev_freq, prev_bw;
+       int ret;
+       u8 buf[5];
+
+       if (priv->i2c_props.adap == NULL)
+               return -EINVAL;
+
+       prev_freq = priv->frequency;
+       prev_bw   = priv->bandwidth;
+
+       frequency = simple_dvb_configure(fe, buf+1, delsys, freq, bw);
+       if (frequency == 0)
+               return -EINVAL;
+
+       buf[0] = priv->i2c_props.addr;
+
+       priv->frequency = frequency;
+       priv->bandwidth = bw;
+
+       /* put analog demod in standby when tuning digital */
+       if (fe->ops.analog_ops.standby)
+               fe->ops.analog_ops.standby(fe);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       /* buf[0] contains the i2c address, but *
+        * we already have it in i2c_props.addr */
+       ret = tuner_i2c_xfer_send(&priv->i2c_props, buf+1, 4);
+       if (ret != 4)
+               goto fail;
+
+       return 0;
+fail:
+       /* calc_regs sets frequency and bandwidth. if we failed, unset them */
+       priv->frequency = prev_freq;
+       priv->bandwidth = prev_bw;
+
+       return ret;
+}
+
+static int simple_init(struct dvb_frontend *fe)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+
+       if (priv->i2c_props.adap == NULL)
+               return -EINVAL;
+
+       if (priv->tun->initdata) {
+               int ret;
+
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+
+               ret = tuner_i2c_xfer_send(&priv->i2c_props,
+                                         priv->tun->initdata + 1,
+                                         priv->tun->initdata[0]);
+               if (ret != priv->tun->initdata[0])
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int simple_sleep(struct dvb_frontend *fe)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+
+       if (priv->i2c_props.adap == NULL)
+               return -EINVAL;
+
+       if (priv->tun->sleepdata) {
+               int ret;
+
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+
+               ret = tuner_i2c_xfer_send(&priv->i2c_props,
+                                         priv->tun->sleepdata + 1,
+                                         priv->tun->sleepdata[0]);
+               if (ret != priv->tun->sleepdata[0])
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int simple_release(struct dvb_frontend *fe)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+
+       mutex_lock(&tuner_simple_list_mutex);
+
+       if (priv)
+               hybrid_tuner_release_state(priv);
+
+       mutex_unlock(&tuner_simple_list_mutex);
+
+       fe->tuner_priv = NULL;
+
+       return 0;
+}
+
+static int simple_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static int simple_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       *bandwidth = priv->bandwidth;
+       return 0;
+}
+
+static struct dvb_tuner_ops simple_tuner_ops = {
+       .init              = simple_init,
+       .sleep             = simple_sleep,
+       .set_analog_params = simple_set_params,
+       .set_params        = simple_dvb_set_params,
+       .calc_regs         = simple_dvb_calc_regs,
+       .release           = simple_release,
+       .get_frequency     = simple_get_frequency,
+       .get_bandwidth     = simple_get_bandwidth,
+       .get_status        = simple_get_status,
+       .get_rf_strength   = simple_get_rf_strength,
+};
+
+struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
+                                        struct i2c_adapter *i2c_adap,
+                                        u8 i2c_addr,
+                                        unsigned int type)
+{
+       struct tuner_simple_priv *priv = NULL;
+       int instance;
+
+       if (type >= tuner_count) {
+               printk(KERN_WARNING "%s: invalid tuner type: %d (max: %d)\n",
+                      __func__, type, tuner_count-1);
+               return NULL;
+       }
+
+       /* If i2c_adap is set, check that the tuner is at the correct address.
+        * Otherwise, if i2c_adap is NULL, the tuner will be programmed directly
+        * by the digital demod via calc_regs.
+        */
+       if (i2c_adap != NULL) {
+               u8 b[1];
+               struct i2c_msg msg = {
+                       .addr = i2c_addr, .flags = I2C_M_RD,
+                       .buf = b, .len = 1,
+               };
+
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+
+               if (1 != i2c_transfer(i2c_adap, &msg, 1))
+                       printk(KERN_WARNING "tuner-simple %d-%04x: "
+                              "unable to probe %s, proceeding anyway.",
+                              i2c_adapter_id(i2c_adap), i2c_addr,
+                              tuners[type].name);
+
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       mutex_lock(&tuner_simple_list_mutex);
+
+       instance = hybrid_tuner_request_state(struct tuner_simple_priv, priv,
+                                             hybrid_tuner_instance_list,
+                                             i2c_adap, i2c_addr,
+                                             "tuner-simple");
+       switch (instance) {
+       case 0:
+               mutex_unlock(&tuner_simple_list_mutex);
+               return NULL;
+       case 1:
+               fe->tuner_priv = priv;
+
+               priv->type = type;
+               priv->tun  = &tuners[type];
+               priv->nr   = simple_devcount++;
+               break;
+       default:
+               fe->tuner_priv = priv;
+               break;
+       }
+
+       mutex_unlock(&tuner_simple_list_mutex);
+
+       memcpy(&fe->ops.tuner_ops, &simple_tuner_ops,
+              sizeof(struct dvb_tuner_ops));
+
+       if (type != priv->type)
+               tuner_warn("couldn't set type to %d. Using %d (%s) instead\n",
+                           type, priv->type, priv->tun->name);
+       else
+               tuner_info("type set to %d (%s)\n",
+                          priv->type, priv->tun->name);
+
+       if ((debug) || ((atv_input[priv->nr] > 0) ||
+                       (dtv_input[priv->nr] > 0))) {
+               if (0 == atv_input[priv->nr])
+                       tuner_info("tuner %d atv rf input will be "
+                                  "autoselected\n", priv->nr);
+               else
+                       tuner_info("tuner %d atv rf input will be "
+                                  "set to input %d (insmod option)\n",
+                                  priv->nr, atv_input[priv->nr]);
+               if (0 == dtv_input[priv->nr])
+                       tuner_info("tuner %d dtv rf input will be "
+                                  "autoselected\n", priv->nr);
+               else
+                       tuner_info("tuner %d dtv rf input will be "
+                                  "set to input %d (insmod option)\n",
+                                  priv->nr, dtv_input[priv->nr]);
+       }
+
+       strlcpy(fe->ops.tuner_ops.info.name, priv->tun->name,
+               sizeof(fe->ops.tuner_ops.info.name));
+
+       return fe;
+}
+EXPORT_SYMBOL_GPL(simple_tuner_attach);
+
+MODULE_DESCRIPTION("Simple 4-control-bytes style tuner driver");
+MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
+MODULE_LICENSE("GPL");
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/tuners/tuner-simple.h b/drivers/media/tuners/tuner-simple.h
new file mode 100644 (file)
index 0000000..381fa5d
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+    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 __TUNER_SIMPLE_H__
+#define __TUNER_SIMPLE_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+#if defined(CONFIG_MEDIA_TUNER_SIMPLE) || (defined(CONFIG_MEDIA_TUNER_SIMPLE_MODULE) && defined(MODULE))
+extern struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
+                                               struct i2c_adapter *i2c_adap,
+                                               u8 i2c_addr,
+                                               unsigned int type);
+#else
+static inline struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
+                                                      struct i2c_adapter *i2c_adap,
+                                                      u8 i2c_addr,
+                                                      unsigned int type)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif /* __TUNER_SIMPLE_H__ */
diff --git a/drivers/media/tuners/tuner-types.c b/drivers/media/tuners/tuner-types.c
new file mode 100644 (file)
index 0000000..2da4440
--- /dev/null
@@ -0,0 +1,1883 @@
+/*
+ *
+ * i2c tv tuner chip device type database.
+ *
+ */
+
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <media/tuner.h>
+#include <media/tuner-types.h>
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ *     The floats in the tuner struct are computed at compile time
+ *     by gcc and cast back to integers. Thus we don't violate the
+ *     "no float in kernel" rule.
+ *
+ *     A tuner_range may be referenced by multiple tuner_params structs.
+ *     There are many duplicates in here. Reusing tuner_range structs,
+ *     rather than defining new ones for each tuner, will cut down on
+ *     memory usage, and is preferred when possible.
+ *
+ *     Each tuner_params array may contain one or more elements, one
+ *     for each video standard.
+ *
+ *     FIXME: tuner_params struct contains an element, tda988x. We must
+ *     set this for all tuners that contain a tda988x chip, and then we
+ *     can remove this setting from the various card structs.
+ *
+ *     FIXME: Right now, all tuners are using the first tuner_params[]
+ *     array element for analog mode. In the future, we will be merging
+ *     similar tuner definitions together, such that each tuner definition
+ *     will have a tuner_params struct for each available video standard.
+ *     At that point, the tuner_params[] array element will be chosen
+ *     based on the video standard in use.
+ */
+
+/* The following was taken from dvb-pll.c: */
+
+/* Set AGC TOP value to 103 dBuV:
+ *     0x80 = Control Byte
+ *     0x40 = 250 uA charge pump (irrelevant)
+ *     0x18 = Aux Byte to follow
+ *     0x06 = 64.5 kHz divider (irrelevant)
+ *     0x01 = Disable Vt (aka sleep)
+ *
+ *     0x00 = AGC Time constant 2s Iagc = 300 nA (vs 0x80 = 9 nA)
+ *     0x50 = AGC Take over point = 103 dBuV
+ */
+static u8 tua603x_agc103[] = { 2, 0x80|0x40|0x18|0x06|0x01, 0x00|0x50 };
+
+/*     0x04 = 166.67 kHz divider
+ *
+ *     0x80 = AGC Time constant 50ms Iagc = 9 uA
+ *     0x20 = AGC Take over point = 112 dBuV
+ */
+static u8 tua603x_agc112[] = { 2, 0x80|0x40|0x18|0x04|0x01, 0x80|0x20 };
+
+/* 0-9 */
+/* ------------ TUNER_TEMIC_PAL - TEMIC PAL ------------ */
+
+static struct tuner_range tuner_temic_pal_ranges[] = {
+       { 16 * 140.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 463.25 /*MHz*/, 0x8e, 0x04, },
+       { 16 * 999.99        , 0x8e, 0x01, },
+};
+
+static struct tuner_params tuner_temic_pal_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_temic_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_temic_pal_ranges),
+       },
+};
+
+/* ------------ TUNER_PHILIPS_PAL_I - Philips PAL_I ------------ */
+
+static struct tuner_range tuner_philips_pal_i_ranges[] = {
+       { 16 * 140.25 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 463.25 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
+};
+
+static struct tuner_params tuner_philips_pal_i_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_philips_pal_i_ranges,
+               .count  = ARRAY_SIZE(tuner_philips_pal_i_ranges),
+       },
+};
+
+/* ------------ TUNER_PHILIPS_NTSC - Philips NTSC ------------ */
+
+static struct tuner_range tuner_philips_ntsc_ranges[] = {
+       { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 451.25 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
+};
+
+static struct tuner_params tuner_philips_ntsc_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_philips_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_philips_ntsc_ranges),
+               .cb_first_if_lower_freq = 1,
+       },
+};
+
+/* ------------ TUNER_PHILIPS_SECAM - Philips SECAM ------------ */
+
+static struct tuner_range tuner_philips_secam_ranges[] = {
+       { 16 * 168.25 /*MHz*/, 0x8e, 0xa7, },
+       { 16 * 447.25 /*MHz*/, 0x8e, 0x97, },
+       { 16 * 999.99        , 0x8e, 0x37, },
+};
+
+static struct tuner_params tuner_philips_secam_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_SECAM,
+               .ranges = tuner_philips_secam_ranges,
+               .count  = ARRAY_SIZE(tuner_philips_secam_ranges),
+               .cb_first_if_lower_freq = 1,
+       },
+};
+
+/* ------------ TUNER_PHILIPS_PAL - Philips PAL ------------ */
+
+static struct tuner_range tuner_philips_pal_ranges[] = {
+       { 16 * 168.25 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 447.25 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
+};
+
+static struct tuner_params tuner_philips_pal_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_philips_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_philips_pal_ranges),
+               .cb_first_if_lower_freq = 1,
+       },
+};
+
+/* ------------ TUNER_TEMIC_NTSC - TEMIC NTSC ------------ */
+
+static struct tuner_range tuner_temic_ntsc_ranges[] = {
+       { 16 * 157.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 463.25 /*MHz*/, 0x8e, 0x04, },
+       { 16 * 999.99        , 0x8e, 0x01, },
+};
+
+static struct tuner_params tuner_temic_ntsc_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_temic_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_temic_ntsc_ranges),
+       },
+};
+
+/* ------------ TUNER_TEMIC_PAL_I - TEMIC PAL_I ------------ */
+
+static struct tuner_range tuner_temic_pal_i_ranges[] = {
+       { 16 * 170.00 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 450.00 /*MHz*/, 0x8e, 0x04, },
+       { 16 * 999.99        , 0x8e, 0x01, },
+};
+
+static struct tuner_params tuner_temic_pal_i_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_temic_pal_i_ranges,
+               .count  = ARRAY_SIZE(tuner_temic_pal_i_ranges),
+       },
+};
+
+/* ------------ TUNER_TEMIC_4036FY5_NTSC - TEMIC NTSC ------------ */
+
+static struct tuner_range tuner_temic_4036fy5_ntsc_ranges[] = {
+       { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 463.25 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
+};
+
+static struct tuner_params tuner_temic_4036fy5_ntsc_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_temic_4036fy5_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_temic_4036fy5_ntsc_ranges),
+       },
+};
+
+/* ------------ TUNER_ALPS_TSBH1_NTSC - TEMIC NTSC ------------ */
+
+static struct tuner_range tuner_alps_tsb_1_ranges[] = {
+       { 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 385.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x08, },
+};
+
+static struct tuner_params tuner_alps_tsbh1_ntsc_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_alps_tsb_1_ranges,
+               .count  = ARRAY_SIZE(tuner_alps_tsb_1_ranges),
+       },
+};
+
+/* 10-19 */
+/* ------------ TUNER_ALPS_TSBE1_PAL - TEMIC PAL ------------ */
+
+static struct tuner_params tuner_alps_tsb_1_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_alps_tsb_1_ranges,
+               .count  = ARRAY_SIZE(tuner_alps_tsb_1_ranges),
+       },
+};
+
+/* ------------ TUNER_ALPS_TSBB5_PAL_I - Alps PAL_I ------------ */
+
+static struct tuner_range tuner_alps_tsb_5_pal_ranges[] = {
+       { 16 * 133.25 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 351.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x08, },
+};
+
+static struct tuner_params tuner_alps_tsbb5_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_alps_tsb_5_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges),
+       },
+};
+
+/* ------------ TUNER_ALPS_TSBE5_PAL - Alps PAL ------------ */
+
+static struct tuner_params tuner_alps_tsbe5_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_alps_tsb_5_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges),
+       },
+};
+
+/* ------------ TUNER_ALPS_TSBC5_PAL - Alps PAL ------------ */
+
+static struct tuner_params tuner_alps_tsbc5_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_alps_tsb_5_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges),
+       },
+};
+
+/* ------------ TUNER_TEMIC_4006FH5_PAL - TEMIC PAL ------------ */
+
+static struct tuner_range tuner_lg_pal_ranges[] = {
+       { 16 * 170.00 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 450.00 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
+};
+
+static struct tuner_params tuner_temic_4006fh5_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_lg_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
+       },
+};
+
+/* ------------ TUNER_ALPS_TSHC6_NTSC - Alps NTSC ------------ */
+
+static struct tuner_range tuner_alps_tshc6_ntsc_ranges[] = {
+       { 16 * 137.25 /*MHz*/, 0x8e, 0x14, },
+       { 16 * 385.25 /*MHz*/, 0x8e, 0x12, },
+       { 16 * 999.99        , 0x8e, 0x11, },
+};
+
+static struct tuner_params tuner_alps_tshc6_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_alps_tshc6_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_alps_tshc6_ntsc_ranges),
+       },
+};
+
+/* ------------ TUNER_TEMIC_PAL_DK - TEMIC PAL ------------ */
+
+static struct tuner_range tuner_temic_pal_dk_ranges[] = {
+       { 16 * 168.25 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 456.25 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
+};
+
+static struct tuner_params tuner_temic_pal_dk_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_temic_pal_dk_ranges,
+               .count  = ARRAY_SIZE(tuner_temic_pal_dk_ranges),
+       },
+};
+
+/* ------------ TUNER_PHILIPS_NTSC_M - Philips NTSC ------------ */
+
+static struct tuner_range tuner_philips_ntsc_m_ranges[] = {
+       { 16 * 160.00 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 454.00 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
+};
+
+static struct tuner_params tuner_philips_ntsc_m_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_philips_ntsc_m_ranges,
+               .count  = ARRAY_SIZE(tuner_philips_ntsc_m_ranges),
+       },
+};
+
+/* ------------ TUNER_TEMIC_4066FY5_PAL_I - TEMIC PAL_I ------------ */
+
+static struct tuner_range tuner_temic_40x6f_5_pal_ranges[] = {
+       { 16 * 169.00 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 454.00 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
+};
+
+static struct tuner_params tuner_temic_4066fy5_pal_i_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_temic_40x6f_5_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges),
+       },
+};
+
+/* ------------ TUNER_TEMIC_4006FN5_MULTI_PAL - TEMIC PAL ------------ */
+
+static struct tuner_params tuner_temic_4006fn5_multi_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_temic_40x6f_5_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges),
+       },
+};
+
+/* 20-29 */
+/* ------------ TUNER_TEMIC_4009FR5_PAL - TEMIC PAL ------------ */
+
+static struct tuner_range tuner_temic_4009f_5_pal_ranges[] = {
+       { 16 * 141.00 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 464.00 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
+};
+
+static struct tuner_params tuner_temic_4009f_5_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_temic_4009f_5_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
+       },
+};
+
+/* ------------ TUNER_TEMIC_4039FR5_NTSC - TEMIC NTSC ------------ */
+
+static struct tuner_range tuner_temic_4x3x_f_5_ntsc_ranges[] = {
+       { 16 * 158.00 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 453.00 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
+};
+
+static struct tuner_params tuner_temic_4039fr5_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_temic_4x3x_f_5_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_temic_4x3x_f_5_ntsc_ranges),
+       },
+};
+
+/* ------------ TUNER_TEMIC_4046FM5 - TEMIC PAL ------------ */
+
+static struct tuner_params tuner_temic_4046fm5_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_temic_40x6f_5_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges),
+       },
+};
+
+/* ------------ TUNER_PHILIPS_PAL_DK - Philips PAL ------------ */
+
+static struct tuner_params tuner_philips_pal_dk_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_lg_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
+       },
+};
+
+/* ------------ TUNER_PHILIPS_FQ1216ME - Philips PAL ------------ */
+
+static struct tuner_params tuner_philips_fq1216me_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_lg_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
+               .has_tda9887 = 1,
+               .port1_active = 1,
+               .port2_active = 1,
+               .port2_invert_for_secam_lc = 1,
+       },
+};
+
+/* ------------ TUNER_LG_PAL_I_FM - LGINNOTEK PAL_I ------------ */
+
+static struct tuner_params tuner_lg_pal_i_fm_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_lg_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
+       },
+};
+
+/* ------------ TUNER_LG_PAL_I - LGINNOTEK PAL_I ------------ */
+
+static struct tuner_params tuner_lg_pal_i_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_lg_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
+       },
+};
+
+/* ------------ TUNER_LG_NTSC_FM - LGINNOTEK NTSC ------------ */
+
+static struct tuner_range tuner_lg_ntsc_fm_ranges[] = {
+       { 16 * 210.00 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 497.00 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
+};
+
+static struct tuner_params tuner_lg_ntsc_fm_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_lg_ntsc_fm_ranges,
+               .count  = ARRAY_SIZE(tuner_lg_ntsc_fm_ranges),
+       },
+};
+
+/* ------------ TUNER_LG_PAL_FM - LGINNOTEK PAL ------------ */
+
+static struct tuner_params tuner_lg_pal_fm_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_lg_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
+       },
+};
+
+/* ------------ TUNER_LG_PAL - LGINNOTEK PAL ------------ */
+
+static struct tuner_params tuner_lg_pal_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_lg_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_lg_pal_ranges),
+       },
+};
+
+/* 30-39 */
+/* ------------ TUNER_TEMIC_4009FN5_MULTI_PAL_FM - TEMIC PAL ------------ */
+
+static struct tuner_params tuner_temic_4009_fn5_multi_pal_fm_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_temic_4009f_5_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
+       },
+};
+
+/* ------------ TUNER_SHARP_2U5JF5540_NTSC - SHARP NTSC ------------ */
+
+static struct tuner_range tuner_sharp_2u5jf5540_ntsc_ranges[] = {
+       { 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 317.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x08, },
+};
+
+static struct tuner_params tuner_sharp_2u5jf5540_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_sharp_2u5jf5540_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_sharp_2u5jf5540_ntsc_ranges),
+       },
+};
+
+/* ------------ TUNER_Samsung_PAL_TCPM9091PD27 - Samsung PAL ------------ */
+
+static struct tuner_range tuner_samsung_pal_tcpm9091pd27_ranges[] = {
+       { 16 * 169 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 464 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99     , 0x8e, 0x30, },
+};
+
+static struct tuner_params tuner_samsung_pal_tcpm9091pd27_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_samsung_pal_tcpm9091pd27_ranges,
+               .count  = ARRAY_SIZE(tuner_samsung_pal_tcpm9091pd27_ranges),
+       },
+};
+
+/* ------------ TUNER_TEMIC_4106FH5 - TEMIC PAL ------------ */
+
+static struct tuner_params tuner_temic_4106fh5_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_temic_4009f_5_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
+       },
+};
+
+/* ------------ TUNER_TEMIC_4012FY5 - TEMIC PAL ------------ */
+
+static struct tuner_params tuner_temic_4012fy5_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_temic_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_temic_pal_ranges),
+       },
+};
+
+/* ------------ TUNER_TEMIC_4136FY5 - TEMIC NTSC ------------ */
+
+static struct tuner_params tuner_temic_4136_fy5_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_temic_4x3x_f_5_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_temic_4x3x_f_5_ntsc_ranges),
+       },
+};
+
+/* ------------ TUNER_LG_PAL_NEW_TAPC - LGINNOTEK PAL ------------ */
+
+static struct tuner_range tuner_lg_new_tapc_ranges[] = {
+       { 16 * 170.00 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 450.00 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x08, },
+};
+
+static struct tuner_params tuner_lg_pal_new_tapc_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_lg_new_tapc_ranges,
+               .count  = ARRAY_SIZE(tuner_lg_new_tapc_ranges),
+       },
+};
+
+/* ------------ TUNER_PHILIPS_FM1216ME_MK3 - Philips PAL ------------ */
+
+static struct tuner_range tuner_fm1216me_mk3_pal_ranges[] = {
+       { 16 * 158.00 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 442.00 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x04, },
+};
+
+static struct tuner_params tuner_fm1216me_mk3_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_fm1216me_mk3_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges),
+               .cb_first_if_lower_freq = 1,
+               .has_tda9887 = 1,
+               .port1_active = 1,
+               .port2_active = 1,
+               .port2_invert_for_secam_lc = 1,
+               .port1_fm_high_sensitivity = 1,
+               .default_top_mid = -2,
+               .default_top_secam_mid = -2,
+               .default_top_secam_high = -2,
+       },
+};
+
+/* ------------ TUNER_PHILIPS_FM1216MK5 - Philips PAL ------------ */
+
+static struct tuner_range tuner_fm1216mk5_pal_ranges[] = {
+       { 16 * 158.00 /*MHz*/, 0xce, 0x01, },
+       { 16 * 441.00 /*MHz*/, 0xce, 0x02, },
+       { 16 * 864.00        , 0xce, 0x04, },
+};
+
+static struct tuner_params tuner_fm1216mk5_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_fm1216mk5_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_fm1216mk5_pal_ranges),
+               .cb_first_if_lower_freq = 1,
+               .has_tda9887 = 1,
+               .port1_active = 1,
+               .port2_active = 1,
+               .port2_invert_for_secam_lc = 1,
+               .port1_fm_high_sensitivity = 1,
+               .default_top_mid = -2,
+               .default_top_secam_mid = -2,
+               .default_top_secam_high = -2,
+       },
+};
+
+/* ------------ TUNER_LG_NTSC_NEW_TAPC - LGINNOTEK NTSC ------------ */
+
+static struct tuner_params tuner_lg_ntsc_new_tapc_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_lg_new_tapc_ranges,
+               .count  = ARRAY_SIZE(tuner_lg_new_tapc_ranges),
+       },
+};
+
+/* 40-49 */
+/* ------------ TUNER_HITACHI_NTSC - HITACHI NTSC ------------ */
+
+static struct tuner_params tuner_hitachi_ntsc_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_lg_new_tapc_ranges,
+               .count  = ARRAY_SIZE(tuner_lg_new_tapc_ranges),
+       },
+};
+
+/* ------------ TUNER_PHILIPS_PAL_MK - Philips PAL ------------ */
+
+static struct tuner_range tuner_philips_pal_mk_pal_ranges[] = {
+       { 16 * 140.25 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 463.25 /*MHz*/, 0x8e, 0xc2, },
+       { 16 * 999.99        , 0x8e, 0xcf, },
+};
+
+static struct tuner_params tuner_philips_pal_mk_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_philips_pal_mk_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_philips_pal_mk_pal_ranges),
+       },
+};
+
+/* ---- TUNER_PHILIPS_FCV1236D - Philips FCV1236D (ATSC/NTSC) ---- */
+
+static struct tuner_range tuner_philips_fcv1236d_ntsc_ranges[] = {
+       { 16 * 157.25 /*MHz*/, 0x8e, 0xa2, },
+       { 16 * 451.25 /*MHz*/, 0x8e, 0x92, },
+       { 16 * 999.99        , 0x8e, 0x32, },
+};
+
+static struct tuner_range tuner_philips_fcv1236d_atsc_ranges[] = {
+       { 16 * 159.00 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 453.00 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
+};
+
+static struct tuner_params tuner_philips_fcv1236d_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_philips_fcv1236d_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_philips_fcv1236d_ntsc_ranges),
+       },
+       {
+               .type   = TUNER_PARAM_TYPE_DIGITAL,
+               .ranges = tuner_philips_fcv1236d_atsc_ranges,
+               .count  = ARRAY_SIZE(tuner_philips_fcv1236d_atsc_ranges),
+               .iffreq = 16 * 44.00,
+       },
+};
+
+/* ------------ TUNER_PHILIPS_FM1236_MK3 - Philips NTSC ------------ */
+
+static struct tuner_range tuner_fm1236_mk3_ntsc_ranges[] = {
+       { 16 * 160.00 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 442.00 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x04, },
+};
+
+static struct tuner_params tuner_fm1236_mk3_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_fm1236_mk3_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
+               .cb_first_if_lower_freq = 1,
+               .has_tda9887 = 1,
+               .port1_active = 1,
+               .port2_active = 1,
+               .port1_fm_high_sensitivity = 1,
+       },
+};
+
+/* ------------ TUNER_PHILIPS_4IN1 - Philips NTSC ------------ */
+
+static struct tuner_params tuner_philips_4in1_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_fm1236_mk3_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
+       },
+};
+
+/* ------------ TUNER_MICROTUNE_4049FM5 - Microtune PAL ------------ */
+
+static struct tuner_params tuner_microtune_4049_fm5_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_temic_4009f_5_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
+               .has_tda9887 = 1,
+               .port1_invert_for_secam_lc = 1,
+               .default_pll_gating_18 = 1,
+               .fm_gain_normal=1,
+               .radio_if = 1, /* 33.3 MHz */
+       },
+};
+
+/* ------------ TUNER_PANASONIC_VP27 - Panasonic NTSC ------------ */
+
+static struct tuner_range tuner_panasonic_vp27_ntsc_ranges[] = {
+       { 16 * 160.00 /*MHz*/, 0xce, 0x01, },
+       { 16 * 454.00 /*MHz*/, 0xce, 0x02, },
+       { 16 * 999.99        , 0xce, 0x08, },
+};
+
+static struct tuner_params tuner_panasonic_vp27_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_panasonic_vp27_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_panasonic_vp27_ntsc_ranges),
+               .has_tda9887 = 1,
+               .intercarrier_mode = 1,
+               .default_top_low = -3,
+               .default_top_mid = -3,
+               .default_top_high = -3,
+       },
+};
+
+/* ------------ TUNER_TNF_8831BGFF - Philips PAL ------------ */
+
+static struct tuner_range tuner_tnf_8831bgff_pal_ranges[] = {
+       { 16 * 161.25 /*MHz*/, 0x8e, 0xa0, },
+       { 16 * 463.25 /*MHz*/, 0x8e, 0x90, },
+       { 16 * 999.99        , 0x8e, 0x30, },
+};
+
+static struct tuner_params tuner_tnf_8831bgff_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_tnf_8831bgff_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_tnf_8831bgff_pal_ranges),
+       },
+};
+
+/* ------------ TUNER_MICROTUNE_4042FI5 - Microtune NTSC ------------ */
+
+static struct tuner_range tuner_microtune_4042fi5_ntsc_ranges[] = {
+       { 16 * 162.00 /*MHz*/, 0x8e, 0xa2, },
+       { 16 * 457.00 /*MHz*/, 0x8e, 0x94, },
+       { 16 * 999.99        , 0x8e, 0x31, },
+};
+
+static struct tuner_range tuner_microtune_4042fi5_atsc_ranges[] = {
+       { 16 * 162.00 /*MHz*/, 0x8e, 0xa1, },
+       { 16 * 457.00 /*MHz*/, 0x8e, 0x91, },
+       { 16 * 999.99        , 0x8e, 0x31, },
+};
+
+static struct tuner_params tuner_microtune_4042fi5_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_microtune_4042fi5_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_microtune_4042fi5_ntsc_ranges),
+       },
+       {
+               .type   = TUNER_PARAM_TYPE_DIGITAL,
+               .ranges = tuner_microtune_4042fi5_atsc_ranges,
+               .count  = ARRAY_SIZE(tuner_microtune_4042fi5_atsc_ranges),
+               .iffreq = 16 * 44.00 /*MHz*/,
+       },
+};
+
+/* 50-59 */
+/* ------------ TUNER_TCL_2002N - TCL NTSC ------------ */
+
+static struct tuner_range tuner_tcl_2002n_ntsc_ranges[] = {
+       { 16 * 172.00 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 448.00 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x08, },
+};
+
+static struct tuner_params tuner_tcl_2002n_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_tcl_2002n_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_tcl_2002n_ntsc_ranges),
+               .cb_first_if_lower_freq = 1,
+       },
+};
+
+/* ------------ TUNER_PHILIPS_FM1256_IH3 - Philips PAL ------------ */
+
+static struct tuner_params tuner_philips_fm1256_ih3_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_fm1236_mk3_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
+               .radio_if = 1, /* 33.3 MHz */
+       },
+};
+
+/* ------------ TUNER_THOMSON_DTT7610 - THOMSON ATSC ------------ */
+
+/* single range used for both ntsc and atsc */
+static struct tuner_range tuner_thomson_dtt7610_ntsc_ranges[] = {
+       { 16 * 157.25 /*MHz*/, 0x8e, 0x39, },
+       { 16 * 454.00 /*MHz*/, 0x8e, 0x3a, },
+       { 16 * 999.99        , 0x8e, 0x3c, },
+};
+
+static struct tuner_params tuner_thomson_dtt7610_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_thomson_dtt7610_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_thomson_dtt7610_ntsc_ranges),
+       },
+       {
+               .type   = TUNER_PARAM_TYPE_DIGITAL,
+               .ranges = tuner_thomson_dtt7610_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_thomson_dtt7610_ntsc_ranges),
+               .iffreq = 16 * 44.00 /*MHz*/,
+       },
+};
+
+/* ------------ TUNER_PHILIPS_FQ1286 - Philips NTSC ------------ */
+
+static struct tuner_range tuner_philips_fq1286_ntsc_ranges[] = {
+       { 16 * 160.00 /*MHz*/, 0x8e, 0x41, },
+       { 16 * 454.00 /*MHz*/, 0x8e, 0x42, },
+       { 16 * 999.99        , 0x8e, 0x04, },
+};
+
+static struct tuner_params tuner_philips_fq1286_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_philips_fq1286_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_philips_fq1286_ntsc_ranges),
+       },
+};
+
+/* ------------ TUNER_TCL_2002MB - TCL PAL ------------ */
+
+static struct tuner_range tuner_tcl_2002mb_pal_ranges[] = {
+       { 16 * 170.00 /*MHz*/, 0xce, 0x01, },
+       { 16 * 450.00 /*MHz*/, 0xce, 0x02, },
+       { 16 * 999.99        , 0xce, 0x08, },
+};
+
+static struct tuner_params tuner_tcl_2002mb_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_tcl_2002mb_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_tcl_2002mb_pal_ranges),
+       },
+};
+
+/* ------------ TUNER_PHILIPS_FQ1216AME_MK4 - Philips PAL ------------ */
+
+static struct tuner_range tuner_philips_fq12_6a___mk4_pal_ranges[] = {
+       { 16 * 160.00 /*MHz*/, 0xce, 0x01, },
+       { 16 * 442.00 /*MHz*/, 0xce, 0x02, },
+       { 16 * 999.99        , 0xce, 0x04, },
+};
+
+static struct tuner_params tuner_philips_fq1216ame_mk4_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_philips_fq12_6a___mk4_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_philips_fq12_6a___mk4_pal_ranges),
+               .has_tda9887 = 1,
+               .port1_active = 1,
+               .port2_invert_for_secam_lc = 1,
+               .default_top_mid = -2,
+               .default_top_secam_low = -2,
+               .default_top_secam_mid = -2,
+               .default_top_secam_high = -2,
+       },
+};
+
+/* ------------ TUNER_PHILIPS_FQ1236A_MK4 - Philips NTSC ------------ */
+
+static struct tuner_params tuner_philips_fq1236a_mk4_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_fm1236_mk3_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
+       },
+};
+
+/* ------------ TUNER_YMEC_TVF_8531MF - Philips NTSC ------------ */
+
+static struct tuner_params tuner_ymec_tvf_8531mf_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_philips_ntsc_m_ranges,
+               .count  = ARRAY_SIZE(tuner_philips_ntsc_m_ranges),
+       },
+};
+
+/* ------------ TUNER_YMEC_TVF_5533MF - Philips NTSC ------------ */
+
+static struct tuner_range tuner_ymec_tvf_5533mf_ntsc_ranges[] = {
+       { 16 * 160.00 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 454.00 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x04, },
+};
+
+static struct tuner_params tuner_ymec_tvf_5533mf_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_ymec_tvf_5533mf_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_ymec_tvf_5533mf_ntsc_ranges),
+       },
+};
+
+/* 60-69 */
+/* ------------ TUNER_THOMSON_DTT761X - THOMSON ATSC ------------ */
+/* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
+
+static struct tuner_range tuner_thomson_dtt761x_ntsc_ranges[] = {
+       { 16 * 145.25 /*MHz*/, 0x8e, 0x39, },
+       { 16 * 415.25 /*MHz*/, 0x8e, 0x3a, },
+       { 16 * 999.99        , 0x8e, 0x3c, },
+};
+
+static struct tuner_range tuner_thomson_dtt761x_atsc_ranges[] = {
+       { 16 * 147.00 /*MHz*/, 0x8e, 0x39, },
+       { 16 * 417.00 /*MHz*/, 0x8e, 0x3a, },
+       { 16 * 999.99        , 0x8e, 0x3c, },
+};
+
+static struct tuner_params tuner_thomson_dtt761x_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_thomson_dtt761x_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_thomson_dtt761x_ntsc_ranges),
+               .has_tda9887 = 1,
+               .fm_gain_normal = 1,
+               .radio_if = 2, /* 41.3 MHz */
+       },
+       {
+               .type   = TUNER_PARAM_TYPE_DIGITAL,
+               .ranges = tuner_thomson_dtt761x_atsc_ranges,
+               .count  = ARRAY_SIZE(tuner_thomson_dtt761x_atsc_ranges),
+               .iffreq = 16 * 44.00, /*MHz*/
+       },
+};
+
+/* ------------ TUNER_TENA_9533_DI - Philips PAL ------------ */
+
+static struct tuner_range tuner_tena_9533_di_pal_ranges[] = {
+       { 16 * 160.25 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 464.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x04, },
+};
+
+static struct tuner_params tuner_tena_9533_di_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_tena_9533_di_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_tena_9533_di_pal_ranges),
+       },
+};
+
+/* ------------ TUNER_TENA_TNF_5337 - Tena tnf5337MFD STD M/N ------------ */
+
+static struct tuner_range tuner_tena_tnf_5337_ntsc_ranges[] = {
+       { 16 * 166.25 /*MHz*/, 0x86, 0x01, },
+       { 16 * 466.25 /*MHz*/, 0x86, 0x02, },
+       { 16 * 999.99        , 0x86, 0x08, },
+};
+
+static struct tuner_params tuner_tena_tnf_5337_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_tena_tnf_5337_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_tena_tnf_5337_ntsc_ranges),
+       },
+};
+
+/* ------------ TUNER_PHILIPS_FMD1216ME(X)_MK3 - Philips PAL ------------ */
+
+static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = {
+       { 16 * 160.00 /*MHz*/, 0x86, 0x51, },
+       { 16 * 442.00 /*MHz*/, 0x86, 0x52, },
+       { 16 * 999.99        , 0x86, 0x54, },
+};
+
+static struct tuner_range tuner_philips_fmd1216me_mk3_dvb_ranges[] = {
+       { 16 * 143.87 /*MHz*/, 0xbc, 0x41 },
+       { 16 * 158.87 /*MHz*/, 0xf4, 0x41 },
+       { 16 * 329.87 /*MHz*/, 0xbc, 0x42 },
+       { 16 * 441.87 /*MHz*/, 0xf4, 0x42 },
+       { 16 * 625.87 /*MHz*/, 0xbc, 0x44 },
+       { 16 * 803.87 /*MHz*/, 0xf4, 0x44 },
+       { 16 * 999.99        , 0xfc, 0x44 },
+};
+
+static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_philips_fmd1216me_mk3_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_pal_ranges),
+               .has_tda9887 = 1,
+               .port1_active = 1,
+               .port2_active = 1,
+               .port2_fm_high_sensitivity = 1,
+               .port2_invert_for_secam_lc = 1,
+               .port1_set_for_fm_mono = 1,
+       },
+       {
+               .type   = TUNER_PARAM_TYPE_DIGITAL,
+               .ranges = tuner_philips_fmd1216me_mk3_dvb_ranges,
+               .count  = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_dvb_ranges),
+               .iffreq = 16 * 36.125, /*MHz*/
+       },
+};
+
+static struct tuner_params tuner_philips_fmd1216mex_mk3_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_philips_fmd1216me_mk3_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_pal_ranges),
+               .has_tda9887 = 1,
+               .port1_active = 1,
+               .port2_active = 1,
+               .port2_fm_high_sensitivity = 1,
+               .port2_invert_for_secam_lc = 1,
+               .port1_set_for_fm_mono = 1,
+               .radio_if = 1,
+               .fm_gain_normal = 1,
+       },
+       {
+               .type   = TUNER_PARAM_TYPE_DIGITAL,
+               .ranges = tuner_philips_fmd1216me_mk3_dvb_ranges,
+               .count  = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_dvb_ranges),
+               .iffreq = 16 * 36.125, /*MHz*/
+       },
+};
+
+/* ------ TUNER_LG_TDVS_H06XF - LG INNOTEK / INFINEON ATSC ----- */
+
+static struct tuner_range tuner_tua6034_ntsc_ranges[] = {
+       { 16 * 165.00 /*MHz*/, 0x8e, 0x01 },
+       { 16 * 450.00 /*MHz*/, 0x8e, 0x02 },
+       { 16 * 999.99        , 0x8e, 0x04 },
+};
+
+static struct tuner_range tuner_tua6034_atsc_ranges[] = {
+       { 16 * 165.00 /*MHz*/, 0xce, 0x01 },
+       { 16 * 450.00 /*MHz*/, 0xce, 0x02 },
+       { 16 * 999.99        , 0xce, 0x04 },
+};
+
+static struct tuner_params tuner_lg_tdvs_h06xf_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_tua6034_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_tua6034_ntsc_ranges),
+       },
+       {
+               .type   = TUNER_PARAM_TYPE_DIGITAL,
+               .ranges = tuner_tua6034_atsc_ranges,
+               .count  = ARRAY_SIZE(tuner_tua6034_atsc_ranges),
+               .iffreq = 16 * 44.00,
+       },
+};
+
+/* ------------ TUNER_YMEC_TVF66T5_B_DFF - Philips PAL ------------ */
+
+static struct tuner_range tuner_ymec_tvf66t5_b_dff_pal_ranges[] = {
+       { 16 * 160.25 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 464.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x08, },
+};
+
+static struct tuner_params tuner_ymec_tvf66t5_b_dff_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_ymec_tvf66t5_b_dff_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_ymec_tvf66t5_b_dff_pal_ranges),
+       },
+};
+
+/* ------------ TUNER_LG_NTSC_TALN_MINI - LGINNOTEK NTSC ------------ */
+
+static struct tuner_range tuner_lg_taln_ntsc_ranges[] = {
+       { 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 373.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x08, },
+};
+
+static struct tuner_range tuner_lg_taln_pal_secam_ranges[] = {
+       { 16 * 150.00 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 425.00 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x08, },
+};
+
+static struct tuner_params tuner_lg_taln_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_lg_taln_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_lg_taln_ntsc_ranges),
+       },{
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_lg_taln_pal_secam_ranges,
+               .count  = ARRAY_SIZE(tuner_lg_taln_pal_secam_ranges),
+       },
+};
+
+/* ------------ TUNER_PHILIPS_TD1316 - Philips PAL ------------ */
+
+static struct tuner_range tuner_philips_td1316_pal_ranges[] = {
+       { 16 * 160.00 /*MHz*/, 0xc8, 0xa1, },
+       { 16 * 442.00 /*MHz*/, 0xc8, 0xa2, },
+       { 16 * 999.99        , 0xc8, 0xa4, },
+};
+
+static struct tuner_range tuner_philips_td1316_dvb_ranges[] = {
+       { 16 *  93.834 /*MHz*/, 0xca, 0x60, },
+       { 16 * 123.834 /*MHz*/, 0xca, 0xa0, },
+       { 16 * 163.834 /*MHz*/, 0xca, 0xc0, },
+       { 16 * 253.834 /*MHz*/, 0xca, 0x60, },
+       { 16 * 383.834 /*MHz*/, 0xca, 0xa0, },
+       { 16 * 443.834 /*MHz*/, 0xca, 0xc0, },
+       { 16 * 583.834 /*MHz*/, 0xca, 0x60, },
+       { 16 * 793.834 /*MHz*/, 0xca, 0xa0, },
+       { 16 * 999.999        , 0xca, 0xe0, },
+};
+
+static struct tuner_params tuner_philips_td1316_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_philips_td1316_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_philips_td1316_pal_ranges),
+       },
+       {
+               .type   = TUNER_PARAM_TYPE_DIGITAL,
+               .ranges = tuner_philips_td1316_dvb_ranges,
+               .count  = ARRAY_SIZE(tuner_philips_td1316_dvb_ranges),
+               .iffreq = 16 * 36.166667 /*MHz*/,
+       },
+};
+
+/* ------------ TUNER_PHILIPS_TUV1236D - Philips ATSC ------------ */
+
+static struct tuner_range tuner_tuv1236d_ntsc_ranges[] = {
+       { 16 * 157.25 /*MHz*/, 0xce, 0x01, },
+       { 16 * 454.00 /*MHz*/, 0xce, 0x02, },
+       { 16 * 999.99        , 0xce, 0x04, },
+};
+
+static struct tuner_range tuner_tuv1236d_atsc_ranges[] = {
+       { 16 * 157.25 /*MHz*/, 0xc6, 0x41, },
+       { 16 * 454.00 /*MHz*/, 0xc6, 0x42, },
+       { 16 * 999.99        , 0xc6, 0x44, },
+};
+
+static struct tuner_params tuner_tuv1236d_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_tuv1236d_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_tuv1236d_ntsc_ranges),
+       },
+       {
+               .type   = TUNER_PARAM_TYPE_DIGITAL,
+               .ranges = tuner_tuv1236d_atsc_ranges,
+               .count  = ARRAY_SIZE(tuner_tuv1236d_atsc_ranges),
+               .iffreq = 16 * 44.00,
+       },
+};
+
+/* ------------ TUNER_TNF_xxx5  - Texas Instruments--------- */
+/* This is known to work with Tenna TVF58t5-MFF and TVF5835 MFF
+ *     but it is expected to work also with other Tenna/Ymec
+ *     models based on TI SN 761677 chip on both PAL and NTSC
+ */
+
+static struct tuner_range tuner_tnf_5335_d_if_pal_ranges[] = {
+       { 16 * 168.25 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 471.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x08, },
+};
+
+static struct tuner_range tuner_tnf_5335mf_ntsc_ranges[] = {
+       { 16 * 169.25 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 469.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x08, },
+};
+
+static struct tuner_params tuner_tnf_5335mf_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_tnf_5335mf_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_tnf_5335mf_ntsc_ranges),
+       },
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_tnf_5335_d_if_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_tnf_5335_d_if_pal_ranges),
+       },
+};
+
+/* 70-79 */
+/* ------------ TUNER_SAMSUNG_TCPN_2121P30A - Samsung NTSC ------------ */
+
+/* '+ 4' turns on the Low Noise Amplifier */
+static struct tuner_range tuner_samsung_tcpn_2121p30a_ntsc_ranges[] = {
+       { 16 * 130.00 /*MHz*/, 0xce, 0x01 + 4, },
+       { 16 * 364.50 /*MHz*/, 0xce, 0x02 + 4, },
+       { 16 * 999.99        , 0xce, 0x08 + 4, },
+};
+
+static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_samsung_tcpn_2121p30a_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_ntsc_ranges),
+       },
+};
+
+/* ------------ TUNER_THOMSON_FE6600 - DViCO Hybrid PAL ------------ */
+
+static struct tuner_range tuner_thomson_fe6600_pal_ranges[] = {
+       { 16 * 160.00 /*MHz*/, 0xfe, 0x11, },
+       { 16 * 442.00 /*MHz*/, 0xf6, 0x12, },
+       { 16 * 999.99        , 0xf6, 0x18, },
+};
+
+static struct tuner_range tuner_thomson_fe6600_dvb_ranges[] = {
+       { 16 * 250.00 /*MHz*/, 0xb4, 0x12, },
+       { 16 * 455.00 /*MHz*/, 0xfe, 0x11, },
+       { 16 * 775.50 /*MHz*/, 0xbc, 0x18, },
+       { 16 * 999.99        , 0xf4, 0x18, },
+};
+
+static struct tuner_params tuner_thomson_fe6600_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_thomson_fe6600_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_thomson_fe6600_pal_ranges),
+       },
+       {
+               .type   = TUNER_PARAM_TYPE_DIGITAL,
+               .ranges = tuner_thomson_fe6600_dvb_ranges,
+               .count  = ARRAY_SIZE(tuner_thomson_fe6600_dvb_ranges),
+               .iffreq = 16 * 36.125 /*MHz*/,
+       },
+};
+
+/* ------------ TUNER_SAMSUNG_TCPG_6121P30A - Samsung PAL ------------ */
+
+/* '+ 4' turns on the Low Noise Amplifier */
+static struct tuner_range tuner_samsung_tcpg_6121p30a_pal_ranges[] = {
+       { 16 * 146.25 /*MHz*/, 0xce, 0x01 + 4, },
+       { 16 * 428.50 /*MHz*/, 0xce, 0x02 + 4, },
+       { 16 * 999.99        , 0xce, 0x08 + 4, },
+};
+
+static struct tuner_params tuner_samsung_tcpg_6121p30a_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_samsung_tcpg_6121p30a_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_pal_ranges),
+               .has_tda9887 = 1,
+               .port1_active = 1,
+               .port2_active = 1,
+               .port2_invert_for_secam_lc = 1,
+       },
+};
+
+/* ------------ TUNER_TCL_MF02GIP-5N-E - TCL MF02GIP-5N ------------ */
+
+static struct tuner_range tuner_tcl_mf02gip_5n_ntsc_ranges[] = {
+       { 16 * 172.00 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 448.00 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x04, },
+};
+
+static struct tuner_params tuner_tcl_mf02gip_5n_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_tcl_mf02gip_5n_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_tcl_mf02gip_5n_ntsc_ranges),
+               .cb_first_if_lower_freq = 1,
+       },
+};
+
+/* 80-89 */
+/* --------- TUNER_PHILIPS_FQ1216LME_MK3 -- active loopthrough, no FM ------- */
+
+static struct tuner_params tuner_fq1216lme_mk3_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_PAL,
+               .ranges = tuner_fm1216me_mk3_pal_ranges,
+               .count  = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges),
+               .cb_first_if_lower_freq = 1, /* not specified, but safe to do */
+               .has_tda9887 = 1, /* TDA9886 */
+               .port1_active = 1,
+               .port2_active = 1,
+               .port2_invert_for_secam_lc = 1,
+               .default_top_low = 4,
+               .default_top_mid = 4,
+               .default_top_high = 4,
+               .default_top_secam_low = 4,
+               .default_top_secam_mid = 4,
+               .default_top_secam_high = 4,
+       },
+};
+
+/* ----- TUNER_PARTSNIC_PTI_5NF05 - Partsnic (Daewoo) PTI-5NF05 NTSC ----- */
+
+static struct tuner_range tuner_partsnic_pti_5nf05_ranges[] = {
+       /* The datasheet specified channel ranges and the bandswitch byte */
+       /* The control byte value of 0x8e is just a guess */
+       { 16 * 133.25 /*MHz*/, 0x8e, 0x01, }, /* Channels    2 -    B */
+       { 16 * 367.25 /*MHz*/, 0x8e, 0x02, }, /* Channels    C - W+11 */
+       { 16 * 999.99        , 0x8e, 0x08, }, /* Channels W+12 -   69 */
+};
+
+static struct tuner_params tuner_partsnic_pti_5nf05_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_partsnic_pti_5nf05_ranges,
+               .count  = ARRAY_SIZE(tuner_partsnic_pti_5nf05_ranges),
+               .cb_first_if_lower_freq = 1, /* not specified but safe to do */
+       },
+};
+
+/* --------- TUNER_PHILIPS_CU1216L - DVB-C NIM ------------------------- */
+
+static struct tuner_range tuner_cu1216l_ranges[] = {
+       { 16 * 160.25 /*MHz*/, 0xce, 0x01 },
+       { 16 * 444.25 /*MHz*/, 0xce, 0x02 },
+       { 16 * 999.99        , 0xce, 0x04 },
+};
+
+static struct tuner_params tuner_philips_cu1216l_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_DIGITAL,
+               .ranges = tuner_cu1216l_ranges,
+               .count  = ARRAY_SIZE(tuner_cu1216l_ranges),
+               .iffreq = 16 * 36.125, /*MHz*/
+       },
+};
+
+/* ---------------------- TUNER_SONY_BTF_PXN01Z ------------------------ */
+
+static struct tuner_range tuner_sony_btf_pxn01z_ranges[] = {
+       { 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
+       { 16 * 367.25 /*MHz*/, 0x8e, 0x02, },
+       { 16 * 999.99        , 0x8e, 0x04, },
+};
+
+static struct tuner_params tuner_sony_btf_pxn01z_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_sony_btf_pxn01z_ranges,
+               .count  = ARRAY_SIZE(tuner_sony_btf_pxn01z_ranges),
+       },
+};
+
+/* ------------ TUNER_PHILIPS_FQ1236_MK5 - Philips NTSC ------------ */
+
+static struct tuner_params tuner_philips_fq1236_mk5_params[] = {
+       {
+               .type   = TUNER_PARAM_TYPE_NTSC,
+               .ranges = tuner_fm1236_mk3_ntsc_ranges,
+               .count  = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
+               .has_tda9887 = 1, /* TDA9885, no FM radio */
+       },
+};
+
+/* --------------------------------------------------------------------- */
+
+struct tunertype tuners[] = {
+       /* 0-9 */
+       [TUNER_TEMIC_PAL] = { /* TEMIC PAL */
+               .name   = "Temic PAL (4002 FH5)",
+               .params = tuner_temic_pal_params,
+               .count  = ARRAY_SIZE(tuner_temic_pal_params),
+       },
+       [TUNER_PHILIPS_PAL_I] = { /* Philips PAL_I */
+               .name   = "Philips PAL_I (FI1246 and compatibles)",
+               .params = tuner_philips_pal_i_params,
+               .count  = ARRAY_SIZE(tuner_philips_pal_i_params),
+       },
+       [TUNER_PHILIPS_NTSC] = { /* Philips NTSC */
+               .name   = "Philips NTSC (FI1236,FM1236 and compatibles)",
+               .params = tuner_philips_ntsc_params,
+               .count  = ARRAY_SIZE(tuner_philips_ntsc_params),
+       },
+       [TUNER_PHILIPS_SECAM] = { /* Philips SECAM */
+               .name   = "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)",
+               .params = tuner_philips_secam_params,
+               .count  = ARRAY_SIZE(tuner_philips_secam_params),
+       },
+       [TUNER_ABSENT] = { /* Tuner Absent */
+               .name   = "NoTuner",
+       },
+       [TUNER_PHILIPS_PAL] = { /* Philips PAL */
+               .name   = "Philips PAL_BG (FI1216 and compatibles)",
+               .params = tuner_philips_pal_params,
+               .count  = ARRAY_SIZE(tuner_philips_pal_params),
+       },
+       [TUNER_TEMIC_NTSC] = { /* TEMIC NTSC */
+               .name   = "Temic NTSC (4032 FY5)",
+               .params = tuner_temic_ntsc_params,
+               .count  = ARRAY_SIZE(tuner_temic_ntsc_params),
+       },
+       [TUNER_TEMIC_PAL_I] = { /* TEMIC PAL_I */
+               .name   = "Temic PAL_I (4062 FY5)",
+               .params = tuner_temic_pal_i_params,
+               .count  = ARRAY_SIZE(tuner_temic_pal_i_params),
+       },
+       [TUNER_TEMIC_4036FY5_NTSC] = { /* TEMIC NTSC */
+               .name   = "Temic NTSC (4036 FY5)",
+               .params = tuner_temic_4036fy5_ntsc_params,
+               .count  = ARRAY_SIZE(tuner_temic_4036fy5_ntsc_params),
+       },
+       [TUNER_ALPS_TSBH1_NTSC] = { /* TEMIC NTSC */
+               .name   = "Alps HSBH1",
+               .params = tuner_alps_tsbh1_ntsc_params,
+               .count  = ARRAY_SIZE(tuner_alps_tsbh1_ntsc_params),
+       },
+
+       /* 10-19 */
+       [TUNER_ALPS_TSBE1_PAL] = { /* TEMIC PAL */
+               .name   = "Alps TSBE1",
+               .params = tuner_alps_tsb_1_params,
+               .count  = ARRAY_SIZE(tuner_alps_tsb_1_params),
+       },
+       [TUNER_ALPS_TSBB5_PAL_I] = { /* Alps PAL_I */
+               .name   = "Alps TSBB5",
+               .params = tuner_alps_tsbb5_params,
+               .count  = ARRAY_SIZE(tuner_alps_tsbb5_params),
+       },
+       [TUNER_ALPS_TSBE5_PAL] = { /* Alps PAL */
+               .name   = "Alps TSBE5",
+               .params = tuner_alps_tsbe5_params,
+               .count  = ARRAY_SIZE(tuner_alps_tsbe5_params),
+       },
+       [TUNER_ALPS_TSBC5_PAL] = { /* Alps PAL */
+               .name   = "Alps TSBC5",
+               .params = tuner_alps_tsbc5_params,
+               .count  = ARRAY_SIZE(tuner_alps_tsbc5_params),
+       },
+       [TUNER_TEMIC_4006FH5_PAL] = { /* TEMIC PAL */
+               .name   = "Temic PAL_BG (4006FH5)",
+               .params = tuner_temic_4006fh5_params,
+               .count  = ARRAY_SIZE(tuner_temic_4006fh5_params),
+       },
+       [TUNER_ALPS_TSHC6_NTSC] = { /* Alps NTSC */
+               .name   = "Alps TSCH6",
+               .params = tuner_alps_tshc6_params,
+               .count  = ARRAY_SIZE(tuner_alps_tshc6_params),
+       },
+       [TUNER_TEMIC_PAL_DK] = { /* TEMIC PAL */
+               .name   = "Temic PAL_DK (4016 FY5)",
+               .params = tuner_temic_pal_dk_params,
+               .count  = ARRAY_SIZE(tuner_temic_pal_dk_params),
+       },
+       [TUNER_PHILIPS_NTSC_M] = { /* Philips NTSC */
+               .name   = "Philips NTSC_M (MK2)",
+               .params = tuner_philips_ntsc_m_params,
+               .count  = ARRAY_SIZE(tuner_philips_ntsc_m_params),
+       },
+       [TUNER_TEMIC_4066FY5_PAL_I] = { /* TEMIC PAL_I */
+               .name   = "Temic PAL_I (4066 FY5)",
+               .params = tuner_temic_4066fy5_pal_i_params,
+               .count  = ARRAY_SIZE(tuner_temic_4066fy5_pal_i_params),
+       },
+       [TUNER_TEMIC_4006FN5_MULTI_PAL] = { /* TEMIC PAL */
+               .name   = "Temic PAL* auto (4006 FN5)",
+               .params = tuner_temic_4006fn5_multi_params,
+               .count  = ARRAY_SIZE(tuner_temic_4006fn5_multi_params),
+       },
+
+       /* 20-29 */
+       [TUNER_TEMIC_4009FR5_PAL] = { /* TEMIC PAL */
+               .name   = "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)",
+               .params = tuner_temic_4009f_5_params,
+               .count  = ARRAY_SIZE(tuner_temic_4009f_5_params),
+       },
+       [TUNER_TEMIC_4039FR5_NTSC] = { /* TEMIC NTSC */
+               .name   = "Temic NTSC (4039 FR5)",
+               .params = tuner_temic_4039fr5_params,
+               .count  = ARRAY_SIZE(tuner_temic_4039fr5_params),
+       },
+       [TUNER_TEMIC_4046FM5] = { /* TEMIC PAL */
+               .name   = "Temic PAL/SECAM multi (4046 FM5)",
+               .params = tuner_temic_4046fm5_params,
+               .count  = ARRAY_SIZE(tuner_temic_4046fm5_params),
+       },
+       [TUNER_PHILIPS_PAL_DK] = { /* Philips PAL */
+               .name   = "Philips PAL_DK (FI1256 and compatibles)",
+               .params = tuner_philips_pal_dk_params,
+               .count  = ARRAY_SIZE(tuner_philips_pal_dk_params),
+       },
+       [TUNER_PHILIPS_FQ1216ME] = { /* Philips PAL */
+               .name   = "Philips PAL/SECAM multi (FQ1216ME)",
+               .params = tuner_philips_fq1216me_params,
+               .count  = ARRAY_SIZE(tuner_philips_fq1216me_params),
+       },
+       [TUNER_LG_PAL_I_FM] = { /* LGINNOTEK PAL_I */
+               .name   = "LG PAL_I+FM (TAPC-I001D)",
+               .params = tuner_lg_pal_i_fm_params,
+               .count  = ARRAY_SIZE(tuner_lg_pal_i_fm_params),
+       },
+       [TUNER_LG_PAL_I] = { /* LGINNOTEK PAL_I */
+               .name   = "LG PAL_I (TAPC-I701D)",
+               .params = tuner_lg_pal_i_params,
+               .count  = ARRAY_SIZE(tuner_lg_pal_i_params),
+       },
+       [TUNER_LG_NTSC_FM] = { /* LGINNOTEK NTSC */
+               .name   = "LG NTSC+FM (TPI8NSR01F)",
+               .params = tuner_lg_ntsc_fm_params,
+               .count  = ARRAY_SIZE(tuner_lg_ntsc_fm_params),
+       },
+       [TUNER_LG_PAL_FM] = { /* LGINNOTEK PAL */
+               .name   = "LG PAL_BG+FM (TPI8PSB01D)",
+               .params = tuner_lg_pal_fm_params,
+               .count  = ARRAY_SIZE(tuner_lg_pal_fm_params),
+       },
+       [TUNER_LG_PAL] = { /* LGINNOTEK PAL */
+               .name   = "LG PAL_BG (TPI8PSB11D)",
+               .params = tuner_lg_pal_params,
+               .count  = ARRAY_SIZE(tuner_lg_pal_params),
+       },
+
+       /* 30-39 */
+       [TUNER_TEMIC_4009FN5_MULTI_PAL_FM] = { /* TEMIC PAL */
+               .name   = "Temic PAL* auto + FM (4009 FN5)",
+               .params = tuner_temic_4009_fn5_multi_pal_fm_params,
+               .count  = ARRAY_SIZE(tuner_temic_4009_fn5_multi_pal_fm_params),
+       },
+       [TUNER_SHARP_2U5JF5540_NTSC] = { /* SHARP NTSC */
+               .name   = "SHARP NTSC_JP (2U5JF5540)",
+               .params = tuner_sharp_2u5jf5540_params,
+               .count  = ARRAY_SIZE(tuner_sharp_2u5jf5540_params),
+       },
+       [TUNER_Samsung_PAL_TCPM9091PD27] = { /* Samsung PAL */
+               .name   = "Samsung PAL TCPM9091PD27",
+               .params = tuner_samsung_pal_tcpm9091pd27_params,
+               .count  = ARRAY_SIZE(tuner_samsung_pal_tcpm9091pd27_params),
+       },
+       [TUNER_MT2032] = { /* Microtune PAL|NTSC */
+               .name   = "MT20xx universal",
+               /* see mt20xx.c for details */ },
+       [TUNER_TEMIC_4106FH5] = { /* TEMIC PAL */
+               .name   = "Temic PAL_BG (4106 FH5)",
+               .params = tuner_temic_4106fh5_params,
+               .count  = ARRAY_SIZE(tuner_temic_4106fh5_params),
+       },
+       [TUNER_TEMIC_4012FY5] = { /* TEMIC PAL */
+               .name   = "Temic PAL_DK/SECAM_L (4012 FY5)",
+               .params = tuner_temic_4012fy5_params,
+               .count  = ARRAY_SIZE(tuner_temic_4012fy5_params),
+       },
+       [TUNER_TEMIC_4136FY5] = { /* TEMIC NTSC */
+               .name   = "Temic NTSC (4136 FY5)",
+               .params = tuner_temic_4136_fy5_params,
+               .count  = ARRAY_SIZE(tuner_temic_4136_fy5_params),
+       },
+       [TUNER_LG_PAL_NEW_TAPC] = { /* LGINNOTEK PAL */
+               .name   = "LG PAL (newer TAPC series)",
+               .params = tuner_lg_pal_new_tapc_params,
+               .count  = ARRAY_SIZE(tuner_lg_pal_new_tapc_params),
+       },
+       [TUNER_PHILIPS_FM1216ME_MK3] = { /* Philips PAL */
+               .name   = "Philips PAL/SECAM multi (FM1216ME MK3)",
+               .params = tuner_fm1216me_mk3_params,
+               .count  = ARRAY_SIZE(tuner_fm1216me_mk3_params),
+       },
+       [TUNER_LG_NTSC_NEW_TAPC] = { /* LGINNOTEK NTSC */
+               .name   = "LG NTSC (newer TAPC series)",
+               .params = tuner_lg_ntsc_new_tapc_params,
+               .count  = ARRAY_SIZE(tuner_lg_ntsc_new_tapc_params),
+       },
+
+       /* 40-49 */
+       [TUNER_HITACHI_NTSC] = { /* HITACHI NTSC */
+               .name   = "HITACHI V7-J180AT",
+               .params = tuner_hitachi_ntsc_params,
+               .count  = ARRAY_SIZE(tuner_hitachi_ntsc_params),
+       },
+       [TUNER_PHILIPS_PAL_MK] = { /* Philips PAL */
+               .name   = "Philips PAL_MK (FI1216 MK)",
+               .params = tuner_philips_pal_mk_params,
+               .count  = ARRAY_SIZE(tuner_philips_pal_mk_params),
+       },
+       [TUNER_PHILIPS_FCV1236D] = { /* Philips ATSC */
+               .name   = "Philips FCV1236D ATSC/NTSC dual in",
+               .params = tuner_philips_fcv1236d_params,
+               .count  = ARRAY_SIZE(tuner_philips_fcv1236d_params),
+               .min = 16 *  53.00,
+               .max = 16 * 803.00,
+               .stepsize = 62500,
+       },
+       [TUNER_PHILIPS_FM1236_MK3] = { /* Philips NTSC */
+               .name   = "Philips NTSC MK3 (FM1236MK3 or FM1236/F)",
+               .params = tuner_fm1236_mk3_params,
+               .count  = ARRAY_SIZE(tuner_fm1236_mk3_params),
+       },
+       [TUNER_PHILIPS_4IN1] = { /* Philips NTSC */
+               .name   = "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)",
+               .params = tuner_philips_4in1_params,
+               .count  = ARRAY_SIZE(tuner_philips_4in1_params),
+       },
+       [TUNER_MICROTUNE_4049FM5] = { /* Microtune PAL */
+               .name   = "Microtune 4049 FM5",
+               .params = tuner_microtune_4049_fm5_params,
+               .count  = ARRAY_SIZE(tuner_microtune_4049_fm5_params),
+       },
+       [TUNER_PANASONIC_VP27] = { /* Panasonic NTSC */
+               .name   = "Panasonic VP27s/ENGE4324D",
+               .params = tuner_panasonic_vp27_params,
+               .count  = ARRAY_SIZE(tuner_panasonic_vp27_params),
+       },
+       [TUNER_LG_NTSC_TAPE] = { /* LGINNOTEK NTSC */
+               .name   = "LG NTSC (TAPE series)",
+               .params = tuner_fm1236_mk3_params,
+               .count  = ARRAY_SIZE(tuner_fm1236_mk3_params),
+       },
+       [TUNER_TNF_8831BGFF] = { /* Philips PAL */
+               .name   = "Tenna TNF 8831 BGFF)",
+               .params = tuner_tnf_8831bgff_params,
+               .count  = ARRAY_SIZE(tuner_tnf_8831bgff_params),
+       },
+       [TUNER_MICROTUNE_4042FI5] = { /* Microtune NTSC */
+               .name   = "Microtune 4042 FI5 ATSC/NTSC dual in",
+               .params = tuner_microtune_4042fi5_params,
+               .count  = ARRAY_SIZE(tuner_microtune_4042fi5_params),
+               .min    = 16 *  57.00,
+               .max    = 16 * 858.00,
+               .stepsize = 62500,
+       },
+
+       /* 50-59 */
+       [TUNER_TCL_2002N] = { /* TCL NTSC */
+               .name   = "TCL 2002N",
+               .params = tuner_tcl_2002n_params,
+               .count  = ARRAY_SIZE(tuner_tcl_2002n_params),
+       },
+       [TUNER_PHILIPS_FM1256_IH3] = { /* Philips PAL */
+               .name   = "Philips PAL/SECAM_D (FM 1256 I-H3)",
+               .params = tuner_philips_fm1256_ih3_params,
+               .count  = ARRAY_SIZE(tuner_philips_fm1256_ih3_params),
+       },
+       [TUNER_THOMSON_DTT7610] = { /* THOMSON ATSC */
+               .name   = "Thomson DTT 7610 (ATSC/NTSC)",
+               .params = tuner_thomson_dtt7610_params,
+               .count  = ARRAY_SIZE(tuner_thomson_dtt7610_params),
+               .min    = 16 *  44.00,
+               .max    = 16 * 958.00,
+               .stepsize = 62500,
+       },
+       [TUNER_PHILIPS_FQ1286] = { /* Philips NTSC */
+               .name   = "Philips FQ1286",
+               .params = tuner_philips_fq1286_params,
+               .count  = ARRAY_SIZE(tuner_philips_fq1286_params),
+       },
+       [TUNER_PHILIPS_TDA8290] = { /* Philips PAL|NTSC */
+               .name   = "Philips/NXP TDA 8290/8295 + 8275/8275A/18271",
+               /* see tda8290.c for details */ },
+       [TUNER_TCL_2002MB] = { /* TCL PAL */
+               .name   = "TCL 2002MB",
+               .params = tuner_tcl_2002mb_params,
+               .count  = ARRAY_SIZE(tuner_tcl_2002mb_params),
+       },
+       [TUNER_PHILIPS_FQ1216AME_MK4] = { /* Philips PAL */
+               .name   = "Philips PAL/SECAM multi (FQ1216AME MK4)",
+               .params = tuner_philips_fq1216ame_mk4_params,
+               .count  = ARRAY_SIZE(tuner_philips_fq1216ame_mk4_params),
+       },
+       [TUNER_PHILIPS_FQ1236A_MK4] = { /* Philips NTSC */
+               .name   = "Philips FQ1236A MK4",
+               .params = tuner_philips_fq1236a_mk4_params,
+               .count  = ARRAY_SIZE(tuner_philips_fq1236a_mk4_params),
+       },
+       [TUNER_YMEC_TVF_8531MF] = { /* Philips NTSC */
+               .name   = "Ymec TVision TVF-8531MF/8831MF/8731MF",
+               .params = tuner_ymec_tvf_8531mf_params,
+               .count  = ARRAY_SIZE(tuner_ymec_tvf_8531mf_params),
+       },
+       [TUNER_YMEC_TVF_5533MF] = { /* Philips NTSC */
+               .name   = "Ymec TVision TVF-5533MF",
+               .params = tuner_ymec_tvf_5533mf_params,
+               .count  = ARRAY_SIZE(tuner_ymec_tvf_5533mf_params),
+       },
+
+       /* 60-69 */
+       [TUNER_THOMSON_DTT761X] = { /* THOMSON ATSC */
+               /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
+               .name   = "Thomson DTT 761X (ATSC/NTSC)",
+               .params = tuner_thomson_dtt761x_params,
+               .count  = ARRAY_SIZE(tuner_thomson_dtt761x_params),
+               .min    = 16 *  57.00,
+               .max    = 16 * 863.00,
+               .stepsize = 62500,
+               .initdata = tua603x_agc103,
+       },
+       [TUNER_TENA_9533_DI] = { /* Philips PAL */
+               .name   = "Tena TNF9533-D/IF/TNF9533-B/DF",
+               .params = tuner_tena_9533_di_params,
+               .count  = ARRAY_SIZE(tuner_tena_9533_di_params),
+       },
+       [TUNER_TEA5767] = { /* Philips RADIO */
+               .name   = "Philips TEA5767HN FM Radio",
+               /* see tea5767.c for details */
+       },
+       [TUNER_PHILIPS_FMD1216ME_MK3] = { /* Philips PAL */
+               .name   = "Philips FMD1216ME MK3 Hybrid Tuner",
+               .params = tuner_philips_fmd1216me_mk3_params,
+               .count  = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_params),
+               .min = 16 *  50.87,
+               .max = 16 * 858.00,
+               .stepsize = 166667,
+               .initdata = tua603x_agc112,
+               .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 },
+       },
+       [TUNER_LG_TDVS_H06XF] = { /* LGINNOTEK ATSC */
+               .name   = "LG TDVS-H06xF", /* H061F, H062F & H064F */
+               .params = tuner_lg_tdvs_h06xf_params,
+               .count  = ARRAY_SIZE(tuner_lg_tdvs_h06xf_params),
+               .min    = 16 *  54.00,
+               .max    = 16 * 863.00,
+               .stepsize = 62500,
+               .initdata = tua603x_agc103,
+       },
+       [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */
+               .name   = "Ymec TVF66T5-B/DFF",
+               .params = tuner_ymec_tvf66t5_b_dff_params,
+               .count  = ARRAY_SIZE(tuner_ymec_tvf66t5_b_dff_params),
+       },
+       [TUNER_LG_TALN] = { /* LGINNOTEK NTSC / PAL / SECAM */
+               .name   = "LG TALN series",
+               .params = tuner_lg_taln_params,
+               .count  = ARRAY_SIZE(tuner_lg_taln_params),
+       },
+       [TUNER_PHILIPS_TD1316] = { /* Philips PAL */
+               .name   = "Philips TD1316 Hybrid Tuner",
+               .params = tuner_philips_td1316_params,
+               .count  = ARRAY_SIZE(tuner_philips_td1316_params),
+               .min    = 16 *  87.00,
+               .max    = 16 * 895.00,
+               .stepsize = 166667,
+       },
+       [TUNER_PHILIPS_TUV1236D] = { /* Philips ATSC */
+               .name   = "Philips TUV1236D ATSC/NTSC dual in",
+               .params = tuner_tuv1236d_params,
+               .count  = ARRAY_SIZE(tuner_tuv1236d_params),
+               .min    = 16 *  54.00,
+               .max    = 16 * 864.00,
+               .stepsize = 62500,
+       },
+       [TUNER_TNF_5335MF] = { /* Tenna PAL/NTSC */
+               .name   = "Tena TNF 5335 and similar models",
+               .params = tuner_tnf_5335mf_params,
+               .count  = ARRAY_SIZE(tuner_tnf_5335mf_params),
+       },
+
+       /* 70-79 */
+       [TUNER_SAMSUNG_TCPN_2121P30A] = { /* Samsung NTSC */
+               .name   = "Samsung TCPN 2121P30A",
+               .params = tuner_samsung_tcpn_2121p30a_params,
+               .count  = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_params),
+       },
+       [TUNER_XC2028] = { /* Xceive 2028 */
+               .name   = "Xceive xc2028/xc3028 tuner",
+               /* see tuner-xc2028.c for details */
+       },
+       [TUNER_THOMSON_FE6600] = { /* Thomson PAL / DVB-T */
+               .name   = "Thomson FE6600",
+               .params = tuner_thomson_fe6600_params,
+               .count  = ARRAY_SIZE(tuner_thomson_fe6600_params),
+               .min    = 16 *  44.25,
+               .max    = 16 * 858.00,
+               .stepsize = 166667,
+       },
+       [TUNER_SAMSUNG_TCPG_6121P30A] = { /* Samsung PAL */
+               .name   = "Samsung TCPG 6121P30A",
+               .params = tuner_samsung_tcpg_6121p30a_params,
+               .count  = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_params),
+       },
+       [TUNER_TDA9887] = { /* Philips TDA 9887 IF PLL Demodulator.
+                               This chip is part of some modern tuners */
+               .name   = "Philips TDA988[5,6,7] IF PLL Demodulator",
+               /* see tda9887.c for details */
+       },
+       [TUNER_TEA5761] = { /* Philips RADIO */
+               .name   = "Philips TEA5761 FM Radio",
+               /* see tea5767.c for details */
+       },
+       [TUNER_XC5000] = { /* Xceive 5000 */
+               .name   = "Xceive 5000 tuner",
+               /* see xc5000.c for details */
+       },
+       [TUNER_XC4000] = { /* Xceive 4000 */
+               .name   = "Xceive 4000 tuner",
+               /* see xc4000.c for details */
+       },
+       [TUNER_TCL_MF02GIP_5N] = { /* TCL tuner MF02GIP-5N-E */
+               .name   = "TCL tuner MF02GIP-5N-E",
+               .params = tuner_tcl_mf02gip_5n_params,
+               .count  = ARRAY_SIZE(tuner_tcl_mf02gip_5n_params),
+       },
+       [TUNER_PHILIPS_FMD1216MEX_MK3] = { /* Philips PAL */
+               .name   = "Philips FMD1216MEX MK3 Hybrid Tuner",
+               .params = tuner_philips_fmd1216mex_mk3_params,
+               .count  = ARRAY_SIZE(tuner_philips_fmd1216mex_mk3_params),
+               .min = 16 *  50.87,
+               .max = 16 * 858.00,
+               .stepsize = 166667,
+               .initdata = tua603x_agc112,
+               .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 },
+       },
+               [TUNER_PHILIPS_FM1216MK5] = { /* Philips PAL */
+               .name   = "Philips PAL/SECAM multi (FM1216 MK5)",
+               .params = tuner_fm1216mk5_params,
+               .count  = ARRAY_SIZE(tuner_fm1216mk5_params),
+       },
+
+       /* 80-89 */
+       [TUNER_PHILIPS_FQ1216LME_MK3] = { /* PAL/SECAM, Loop-thru, no FM */
+               .name = "Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough",
+               .params = tuner_fq1216lme_mk3_params,
+               .count  = ARRAY_SIZE(tuner_fq1216lme_mk3_params),
+       },
+
+       [TUNER_PARTSNIC_PTI_5NF05] = {
+               .name = "Partsnic (Daewoo) PTI-5NF05",
+               .params = tuner_partsnic_pti_5nf05_params,
+               .count  = ARRAY_SIZE(tuner_partsnic_pti_5nf05_params),
+       },
+       [TUNER_PHILIPS_CU1216L] = {
+               .name = "Philips CU1216L",
+               .params = tuner_philips_cu1216l_params,
+               .count  = ARRAY_SIZE(tuner_philips_cu1216l_params),
+               .stepsize = 62500,
+       },
+       [TUNER_NXP_TDA18271] = {
+               .name   = "NXP TDA18271",
+               /* see tda18271-fe.c for details */
+       },
+       [TUNER_SONY_BTF_PXN01Z] = {
+               .name   = "Sony BTF-Pxn01Z",
+               .params = tuner_sony_btf_pxn01z_params,
+               .count  = ARRAY_SIZE(tuner_sony_btf_pxn01z_params),
+       },
+       [TUNER_PHILIPS_FQ1236_MK5] = { /* NTSC, TDA9885, no FM radio */
+               .name   = "Philips FQ1236 MK5",
+               .params = tuner_philips_fq1236_mk5_params,
+               .count  = ARRAY_SIZE(tuner_philips_fq1236_mk5_params),
+       },
+       [TUNER_TENA_TNF_5337] = { /* Tena 5337 MFD */
+               .name   = "Tena TNF5337 MFD",
+               .params = tuner_tena_tnf_5337_params,
+               .count  = ARRAY_SIZE(tuner_tena_tnf_5337_params),
+       },
+       [TUNER_XC5000C] = { /* Xceive 5000C */
+               .name   = "Xceive 5000C tuner",
+               /* see xc5000.c for details */
+       },
+};
+EXPORT_SYMBOL(tuners);
+
+unsigned const int tuner_count = ARRAY_SIZE(tuners);
+EXPORT_SYMBOL(tuner_count);
+
+MODULE_DESCRIPTION("Simple tuner device type database");
+MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/tuner-xc2028-types.h b/drivers/media/tuners/tuner-xc2028-types.h
new file mode 100644 (file)
index 0000000..74dc46a
--- /dev/null
@@ -0,0 +1,141 @@
+/* tuner-xc2028_types
+ *
+ * This file includes internal tipes to be used inside tuner-xc2028.
+ * Shouldn't be included outside tuner-xc2028
+ *
+ * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
+ * This code is placed under the terms of the GNU General Public License v2
+ */
+
+/* xc3028 firmware types */
+
+/* BASE firmware should be loaded before any other firmware */
+#define BASE           (1<<0)
+#define BASE_TYPES     (BASE|F8MHZ|MTS|FM|INPUT1|INPUT2|INIT1)
+
+/* F8MHZ marks BASE firmwares for 8 MHz Bandwidth */
+#define F8MHZ          (1<<1)
+
+/* Multichannel Television Sound (MTS)
+   Those firmwares are capable of using xc2038 DSP to decode audio and
+   produce a baseband audio output on some pins of the chip.
+   There are MTS firmwares for the most used video standards. It should be
+   required to use MTS firmwares, depending on the way audio is routed into
+   the bridge chip
+ */
+#define MTS            (1<<2)
+
+/* FIXME: I have no idea what's the difference between
+   D2620 and D2633 firmwares
+ */
+#define D2620          (1<<3)
+#define D2633          (1<<4)
+
+/* DTV firmwares for 6, 7 and 8 MHz
+   DTV6 - 6MHz - ATSC/DVB-C/DVB-T/ISDB-T/DOCSIS
+   DTV8 - 8MHz - DVB-C/DVB-T
+ */
+#define DTV6           (1 << 5)
+#define QAM            (1 << 6)
+#define DTV7           (1<<7)
+#define DTV78          (1<<8)
+#define DTV8           (1<<9)
+
+#define DTV_TYPES      (D2620|D2633|DTV6|QAM|DTV7|DTV78|DTV8|ATSC)
+
+/* There's a FM | BASE firmware + FM specific firmware (std=0) */
+#define        FM              (1<<10)
+
+#define STD_SPECIFIC_TYPES (MTS|FM|LCD|NOGD)
+
+/* Applies only for FM firmware
+   Makes it use RF input 1 (pin #2) instead of input 2 (pin #4)
+ */
+#define INPUT1         (1<<11)
+
+
+/* LCD firmwares exist only for MTS STD/MN (PAL or NTSC/M)
+       and for non-MTS STD/MN (PAL, NTSC/M or NTSC/Kr)
+       There are variants both with and without NOGD
+       Those firmwares produce better result with LCD displays
+ */
+#define LCD            (1<<12)
+
+/* NOGD firmwares exist only for MTS STD/MN (PAL or NTSC/M)
+       and for non-MTS STD/MN (PAL, NTSC/M or NTSC/Kr)
+       The NOGD firmwares don't have group delay compensation filter
+ */
+#define NOGD           (1<<13)
+
+/* Old firmwares were broken into init0 and init1 */
+#define INIT1          (1<<14)
+
+/* SCODE firmware selects particular behaviours */
+#define MONO           (1 << 15)
+#define ATSC           (1 << 16)
+#define IF             (1 << 17)
+#define LG60           (1 << 18)
+#define ATI638         (1 << 19)
+#define OREN538        (1 << 20)
+#define OREN36         (1 << 21)
+#define TOYOTA388      (1 << 22)
+#define TOYOTA794      (1 << 23)
+#define DIBCOM52       (1 << 24)
+#define ZARLINK456     (1 << 25)
+#define CHINA          (1 << 26)
+#define F6MHZ          (1 << 27)
+#define INPUT2         (1 << 28)
+#define SCODE          (1 << 29)
+
+/* This flag identifies that the scode table has a new format */
+#define HAS_IF         (1 << 30)
+
+/* There are different scode tables for MTS and non-MTS.
+   The MTS firmwares support mono only
+  */
+#define SCODE_TYPES (SCODE | MTS)
+
+
+/* Newer types not defined on videodev2.h.
+   The original idea were to move all those types to videodev2.h, but
+   it seemed overkill, since, with the exception of SECAM/K3, the other
+   types seem to be autodetected.
+   It is not clear where secam/k3 is used, nor we have a feedback of this
+   working or being autodetected by the standard secam firmware.
+ */
+
+#define V4L2_STD_SECAM_K3      (0x04000000)
+
+/* Audio types */
+
+#define V4L2_STD_A2_A          (1LL<<32)
+#define V4L2_STD_A2_B          (1LL<<33)
+#define V4L2_STD_NICAM_A       (1LL<<34)
+#define V4L2_STD_NICAM_B       (1LL<<35)
+#define V4L2_STD_AM            (1LL<<36)
+#define V4L2_STD_BTSC          (1LL<<37)
+#define V4L2_STD_EIAJ          (1LL<<38)
+
+#define V4L2_STD_A2            (V4L2_STD_A2_A    | V4L2_STD_A2_B)
+#define V4L2_STD_NICAM         (V4L2_STD_NICAM_A | V4L2_STD_NICAM_B)
+
+/* To preserve backward compatibilty,
+   (std & V4L2_STD_AUDIO) = 0 means that ALL audio stds are supported
+ */
+
+#define V4L2_STD_AUDIO         (V4L2_STD_A2    | \
+                                V4L2_STD_NICAM | \
+                                V4L2_STD_AM    | \
+                                V4L2_STD_BTSC  | \
+                                V4L2_STD_EIAJ)
+
+/* Used standards with audio restrictions */
+
+#define V4L2_STD_PAL_BG_A2_A   (V4L2_STD_PAL_BG | V4L2_STD_A2_A)
+#define V4L2_STD_PAL_BG_A2_B   (V4L2_STD_PAL_BG | V4L2_STD_A2_B)
+#define V4L2_STD_PAL_BG_NICAM_A        (V4L2_STD_PAL_BG | V4L2_STD_NICAM_A)
+#define V4L2_STD_PAL_BG_NICAM_B        (V4L2_STD_PAL_BG | V4L2_STD_NICAM_B)
+#define V4L2_STD_PAL_DK_A2     (V4L2_STD_PAL_DK | V4L2_STD_A2)
+#define V4L2_STD_PAL_DK_NICAM  (V4L2_STD_PAL_DK | V4L2_STD_NICAM)
+#define V4L2_STD_SECAM_L_NICAM (V4L2_STD_SECAM_L | V4L2_STD_NICAM)
+#define V4L2_STD_SECAM_L_AM    (V4L2_STD_SECAM_L | V4L2_STD_AM)
diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c
new file mode 100644 (file)
index 0000000..7bcb6b0
--- /dev/null
@@ -0,0 +1,1509 @@
+/* tuner-xc2028
+ *
+ * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
+ *
+ * Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com)
+ *       - frontend interface
+ *
+ * This code is placed under the terms of the GNU General Public License v2
+ */
+
+#include <linux/i2c.h>
+#include <asm/div64.h>
+#include <linux/firmware.h>
+#include <linux/videodev2.h>
+#include <linux/delay.h>
+#include <media/tuner.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <asm/unaligned.h>
+#include "tuner-i2c.h"
+#include "tuner-xc2028.h"
+#include "tuner-xc2028-types.h"
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+/* Registers (Write-only) */
+#define XREG_INIT         0x00
+#define XREG_RF_FREQ      0x02
+#define XREG_POWER_DOWN   0x08
+
+/* Registers (Read-only) */
+#define XREG_FREQ_ERROR   0x01
+#define XREG_LOCK         0x02
+#define XREG_VERSION      0x04
+#define XREG_PRODUCT_ID   0x08
+#define XREG_HSYNC_FREQ   0x10
+#define XREG_FRAME_LINES  0x20
+#define XREG_SNR          0x40
+
+#define XREG_ADC_ENV      0x0100
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable verbose debug messages");
+
+static int no_poweroff;
+module_param(no_poweroff, int, 0644);
+MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n"
+       "1 keep device energized and with tuner ready all the times.\n"
+       "  Faster, but consumes more power and keeps the device hotter\n");
+
+static char audio_std[8];
+module_param_string(audio_std, audio_std, sizeof(audio_std), 0);
+MODULE_PARM_DESC(audio_std,
+       "Audio standard. XC3028 audio decoder explicitly "
+       "needs to know what audio\n"
+       "standard is needed for some video standards with audio A2 or NICAM.\n"
+       "The valid values are:\n"
+       "A2\n"
+       "A2/A\n"
+       "A2/B\n"
+       "NICAM\n"
+       "NICAM/A\n"
+       "NICAM/B\n");
+
+static char firmware_name[30];
+module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0);
+MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the "
+                               "default firmware name\n");
+
+static LIST_HEAD(hybrid_tuner_instance_list);
+static DEFINE_MUTEX(xc2028_list_mutex);
+
+/* struct for storing firmware table */
+struct firmware_description {
+       unsigned int  type;
+       v4l2_std_id   id;
+       __u16         int_freq;
+       unsigned char *ptr;
+       unsigned int  size;
+};
+
+struct firmware_properties {
+       unsigned int    type;
+       v4l2_std_id     id;
+       v4l2_std_id     std_req;
+       __u16           int_freq;
+       unsigned int    scode_table;
+       int             scode_nr;
+};
+
+enum xc2028_state {
+       XC2028_NO_FIRMWARE = 0,
+       XC2028_WAITING_FIRMWARE,
+       XC2028_ACTIVE,
+       XC2028_SLEEP,
+       XC2028_NODEV,
+};
+
+struct xc2028_data {
+       struct list_head        hybrid_tuner_instance_list;
+       struct tuner_i2c_props  i2c_props;
+       __u32                   frequency;
+
+       enum xc2028_state       state;
+       const char              *fname;
+
+       struct firmware_description *firm;
+       int                     firm_size;
+       __u16                   firm_version;
+
+       __u16                   hwmodel;
+       __u16                   hwvers;
+
+       struct xc2028_ctrl      ctrl;
+
+       struct firmware_properties cur_fw;
+
+       struct mutex lock;
+};
+
+#define i2c_send(priv, buf, size) ({                                   \
+       int _rc;                                                        \
+       _rc = tuner_i2c_xfer_send(&priv->i2c_props, buf, size);         \
+       if (size != _rc)                                                \
+               tuner_info("i2c output error: rc = %d (should be %d)\n",\
+                          _rc, (int)size);                             \
+       if (priv->ctrl.msleep)                                          \
+               msleep(priv->ctrl.msleep);                              \
+       _rc;                                                            \
+})
+
+#define i2c_rcv(priv, buf, size) ({                                    \
+       int _rc;                                                        \
+       _rc = tuner_i2c_xfer_recv(&priv->i2c_props, buf, size);         \
+       if (size != _rc)                                                \
+               tuner_err("i2c input error: rc = %d (should be %d)\n",  \
+                          _rc, (int)size);                             \
+       _rc;                                                            \
+})
+
+#define i2c_send_recv(priv, obuf, osize, ibuf, isize) ({               \
+       int _rc;                                                        \
+       _rc = tuner_i2c_xfer_send_recv(&priv->i2c_props, obuf, osize,   \
+                                      ibuf, isize);                    \
+       if (isize != _rc)                                               \
+               tuner_err("i2c input error: rc = %d (should be %d)\n",  \
+                          _rc, (int)isize);                            \
+       if (priv->ctrl.msleep)                                          \
+               msleep(priv->ctrl.msleep);                              \
+       _rc;                                                            \
+})
+
+#define send_seq(priv, data...)        ({                                      \
+       static u8 _val[] = data;                                        \
+       int _rc;                                                        \
+       if (sizeof(_val) !=                                             \
+                       (_rc = tuner_i2c_xfer_send(&priv->i2c_props,    \
+                                               _val, sizeof(_val)))) { \
+               tuner_err("Error on line %d: %d\n", __LINE__, _rc);     \
+       } else if (priv->ctrl.msleep)                                   \
+               msleep(priv->ctrl.msleep);                              \
+       _rc;                                                            \
+})
+
+static int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val)
+{
+       unsigned char buf[2];
+       unsigned char ibuf[2];
+
+       tuner_dbg("%s %04x called\n", __func__, reg);
+
+       buf[0] = reg >> 8;
+       buf[1] = (unsigned char) reg;
+
+       if (i2c_send_recv(priv, buf, 2, ibuf, 2) != 2)
+               return -EIO;
+
+       *val = (ibuf[1]) | (ibuf[0] << 8);
+       return 0;
+}
+
+#define dump_firm_type(t)      dump_firm_type_and_int_freq(t, 0)
+static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
+{
+        if (type & BASE)
+               printk("BASE ");
+        if (type & INIT1)
+               printk("INIT1 ");
+        if (type & F8MHZ)
+               printk("F8MHZ ");
+        if (type & MTS)
+               printk("MTS ");
+        if (type & D2620)
+               printk("D2620 ");
+        if (type & D2633)
+               printk("D2633 ");
+        if (type & DTV6)
+               printk("DTV6 ");
+        if (type & QAM)
+               printk("QAM ");
+        if (type & DTV7)
+               printk("DTV7 ");
+        if (type & DTV78)
+               printk("DTV78 ");
+        if (type & DTV8)
+               printk("DTV8 ");
+        if (type & FM)
+               printk("FM ");
+        if (type & INPUT1)
+               printk("INPUT1 ");
+        if (type & LCD)
+               printk("LCD ");
+        if (type & NOGD)
+               printk("NOGD ");
+        if (type & MONO)
+               printk("MONO ");
+        if (type & ATSC)
+               printk("ATSC ");
+        if (type & IF)
+               printk("IF ");
+        if (type & LG60)
+               printk("LG60 ");
+        if (type & ATI638)
+               printk("ATI638 ");
+        if (type & OREN538)
+               printk("OREN538 ");
+        if (type & OREN36)
+               printk("OREN36 ");
+        if (type & TOYOTA388)
+               printk("TOYOTA388 ");
+        if (type & TOYOTA794)
+               printk("TOYOTA794 ");
+        if (type & DIBCOM52)
+               printk("DIBCOM52 ");
+        if (type & ZARLINK456)
+               printk("ZARLINK456 ");
+        if (type & CHINA)
+               printk("CHINA ");
+        if (type & F6MHZ)
+               printk("F6MHZ ");
+        if (type & INPUT2)
+               printk("INPUT2 ");
+        if (type & SCODE)
+               printk("SCODE ");
+        if (type & HAS_IF)
+               printk("HAS_IF_%d ", int_freq);
+}
+
+static  v4l2_std_id parse_audio_std_option(void)
+{
+       if (strcasecmp(audio_std, "A2") == 0)
+               return V4L2_STD_A2;
+       if (strcasecmp(audio_std, "A2/A") == 0)
+               return V4L2_STD_A2_A;
+       if (strcasecmp(audio_std, "A2/B") == 0)
+               return V4L2_STD_A2_B;
+       if (strcasecmp(audio_std, "NICAM") == 0)
+               return V4L2_STD_NICAM;
+       if (strcasecmp(audio_std, "NICAM/A") == 0)
+               return V4L2_STD_NICAM_A;
+       if (strcasecmp(audio_std, "NICAM/B") == 0)
+               return V4L2_STD_NICAM_B;
+
+       return 0;
+}
+
+static int check_device_status(struct xc2028_data *priv)
+{
+       switch (priv->state) {
+       case XC2028_NO_FIRMWARE:
+       case XC2028_WAITING_FIRMWARE:
+               return -EAGAIN;
+       case XC2028_ACTIVE:
+       case XC2028_SLEEP:
+               return 0;
+       case XC2028_NODEV:
+               return -ENODEV;
+       }
+       return 0;
+}
+
+static void free_firmware(struct xc2028_data *priv)
+{
+       int i;
+       tuner_dbg("%s called\n", __func__);
+
+       if (!priv->firm)
+               return;
+
+       for (i = 0; i < priv->firm_size; i++)
+               kfree(priv->firm[i].ptr);
+
+       kfree(priv->firm);
+
+       priv->firm = NULL;
+       priv->firm_size = 0;
+       priv->state = XC2028_NO_FIRMWARE;
+
+       memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
+}
+
+static int load_all_firmwares(struct dvb_frontend *fe,
+                             const struct firmware *fw)
+{
+       struct xc2028_data    *priv = fe->tuner_priv;
+       const unsigned char   *p, *endp;
+       int                   rc = 0;
+       int                   n, n_array;
+       char                  name[33];
+
+       tuner_dbg("%s called\n", __func__);
+
+       p = fw->data;
+       endp = p + fw->size;
+
+       if (fw->size < sizeof(name) - 1 + 2 + 2) {
+               tuner_err("Error: firmware file %s has invalid size!\n",
+                         priv->fname);
+               goto corrupt;
+       }
+
+       memcpy(name, p, sizeof(name) - 1);
+       name[sizeof(name) - 1] = 0;
+       p += sizeof(name) - 1;
+
+       priv->firm_version = get_unaligned_le16(p);
+       p += 2;
+
+       n_array = get_unaligned_le16(p);
+       p += 2;
+
+       tuner_info("Loading %d firmware images from %s, type: %s, ver %d.%d\n",
+                  n_array, priv->fname, name,
+                  priv->firm_version >> 8, priv->firm_version & 0xff);
+
+       priv->firm = kcalloc(n_array, sizeof(*priv->firm), GFP_KERNEL);
+       if (priv->firm == NULL) {
+               tuner_err("Not enough memory to load firmware file.\n");
+               rc = -ENOMEM;
+               goto err;
+       }
+       priv->firm_size = n_array;
+
+       n = -1;
+       while (p < endp) {
+               __u32 type, size;
+               v4l2_std_id id;
+               __u16 int_freq = 0;
+
+               n++;
+               if (n >= n_array) {
+                       tuner_err("More firmware images in file than "
+                                 "were expected!\n");
+                       goto corrupt;
+               }
+
+               /* Checks if there's enough bytes to read */
+               if (endp - p < sizeof(type) + sizeof(id) + sizeof(size))
+                       goto header;
+
+               type = get_unaligned_le32(p);
+               p += sizeof(type);
+
+               id = get_unaligned_le64(p);
+               p += sizeof(id);
+
+               if (type & HAS_IF) {
+                       int_freq = get_unaligned_le16(p);
+                       p += sizeof(int_freq);
+                       if (endp - p < sizeof(size))
+                               goto header;
+               }
+
+               size = get_unaligned_le32(p);
+               p += sizeof(size);
+
+               if (!size || size > endp - p) {
+                       tuner_err("Firmware type ");
+                       dump_firm_type(type);
+                       printk("(%x), id %llx is corrupted "
+                              "(size=%d, expected %d)\n",
+                              type, (unsigned long long)id,
+                              (unsigned)(endp - p), size);
+                       goto corrupt;
+               }
+
+               priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
+               if (priv->firm[n].ptr == NULL) {
+                       tuner_err("Not enough memory to load firmware file.\n");
+                       rc = -ENOMEM;
+                       goto err;
+               }
+               tuner_dbg("Reading firmware type ");
+               if (debug) {
+                       dump_firm_type_and_int_freq(type, int_freq);
+                       printk("(%x), id %llx, size=%d.\n",
+                              type, (unsigned long long)id, size);
+               }
+
+               memcpy(priv->firm[n].ptr, p, size);
+               priv->firm[n].type = type;
+               priv->firm[n].id   = id;
+               priv->firm[n].size = size;
+               priv->firm[n].int_freq = int_freq;
+
+               p += size;
+       }
+
+       if (n + 1 != priv->firm_size) {
+               tuner_err("Firmware file is incomplete!\n");
+               goto corrupt;
+       }
+
+       goto done;
+
+header:
+       tuner_err("Firmware header is incomplete!\n");
+corrupt:
+       rc = -EINVAL;
+       tuner_err("Error: firmware file is corrupted!\n");
+
+err:
+       tuner_info("Releasing partially loaded firmware file.\n");
+       free_firmware(priv);
+
+done:
+       if (rc == 0)
+               tuner_dbg("Firmware files loaded.\n");
+       else
+               priv->state = XC2028_NODEV;
+
+       return rc;
+}
+
+static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
+                        v4l2_std_id *id)
+{
+       struct xc2028_data *priv = fe->tuner_priv;
+       int                 i, best_i = -1, best_nr_matches = 0;
+       unsigned int        type_mask = 0;
+
+       tuner_dbg("%s called, want type=", __func__);
+       if (debug) {
+               dump_firm_type(type);
+               printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
+       }
+
+       if (!priv->firm) {
+               tuner_err("Error! firmware not loaded\n");
+               return -EINVAL;
+       }
+
+       if (((type & ~SCODE) == 0) && (*id == 0))
+               *id = V4L2_STD_PAL;
+
+       if (type & BASE)
+               type_mask = BASE_TYPES;
+       else if (type & SCODE) {
+               type &= SCODE_TYPES;
+               type_mask = SCODE_TYPES & ~HAS_IF;
+       } else if (type & DTV_TYPES)
+               type_mask = DTV_TYPES;
+       else if (type & STD_SPECIFIC_TYPES)
+               type_mask = STD_SPECIFIC_TYPES;
+
+       type &= type_mask;
+
+       if (!(type & SCODE))
+               type_mask = ~0;
+
+       /* Seek for exact match */
+       for (i = 0; i < priv->firm_size; i++) {
+               if ((type == (priv->firm[i].type & type_mask)) &&
+                   (*id == priv->firm[i].id))
+                       goto found;
+       }
+
+       /* Seek for generic video standard match */
+       for (i = 0; i < priv->firm_size; i++) {
+               v4l2_std_id match_mask;
+               int nr_matches;
+
+               if (type != (priv->firm[i].type & type_mask))
+                       continue;
+
+               match_mask = *id & priv->firm[i].id;
+               if (!match_mask)
+                       continue;
+
+               if ((*id & match_mask) == *id)
+                       goto found; /* Supports all the requested standards */
+
+               nr_matches = hweight64(match_mask);
+               if (nr_matches > best_nr_matches) {
+                       best_nr_matches = nr_matches;
+                       best_i = i;
+               }
+       }
+
+       if (best_nr_matches > 0) {
+               tuner_dbg("Selecting best matching firmware (%d bits) for "
+                         "type=", best_nr_matches);
+               dump_firm_type(type);
+               printk("(%x), id %016llx:\n", type, (unsigned long long)*id);
+               i = best_i;
+               goto found;
+       }
+
+       /*FIXME: Would make sense to seek for type "hint" match ? */
+
+       i = -ENOENT;
+       goto ret;
+
+found:
+       *id = priv->firm[i].id;
+
+ret:
+       tuner_dbg("%s firmware for type=", (i < 0) ? "Can't find" : "Found");
+       if (debug) {
+               dump_firm_type(type);
+               printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
+       }
+       return i;
+}
+
+static inline int do_tuner_callback(struct dvb_frontend *fe, int cmd, int arg)
+{
+       struct xc2028_data *priv = fe->tuner_priv;
+
+       /* analog side (tuner-core) uses i2c_adap->algo_data.
+        * digital side is not guaranteed to have algo_data defined.
+        *
+        * digital side will always have fe->dvb defined.
+        * analog side (tuner-core) doesn't (yet) define fe->dvb.
+        */
+
+       return (!fe->callback) ? -EINVAL :
+               fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
+                               fe->dvb->priv : priv->i2c_props.adap->algo_data,
+                            DVB_FRONTEND_COMPONENT_TUNER, cmd, arg);
+}
+
+static int load_firmware(struct dvb_frontend *fe, unsigned int type,
+                        v4l2_std_id *id)
+{
+       struct xc2028_data *priv = fe->tuner_priv;
+       int                pos, rc;
+       unsigned char      *p, *endp, buf[priv->ctrl.max_len];
+
+       tuner_dbg("%s called\n", __func__);
+
+       pos = seek_firmware(fe, type, id);
+       if (pos < 0)
+               return pos;
+
+       tuner_info("Loading firmware for type=");
+       dump_firm_type(priv->firm[pos].type);
+       printk("(%x), id %016llx.\n", priv->firm[pos].type,
+              (unsigned long long)*id);
+
+       p = priv->firm[pos].ptr;
+       endp = p + priv->firm[pos].size;
+
+       while (p < endp) {
+               __u16 size;
+
+               /* Checks if there's enough bytes to read */
+               if (p + sizeof(size) > endp) {
+                       tuner_err("Firmware chunk size is wrong\n");
+                       return -EINVAL;
+               }
+
+               size = le16_to_cpu(*(__u16 *) p);
+               p += sizeof(size);
+
+               if (size == 0xffff)
+                       return 0;
+
+               if (!size) {
+                       /* Special callback command received */
+                       rc = do_tuner_callback(fe, XC2028_TUNER_RESET, 0);
+                       if (rc < 0) {
+                               tuner_err("Error at RESET code %d\n",
+                                          (*p) & 0x7f);
+                               return -EINVAL;
+                       }
+                       continue;
+               }
+               if (size >= 0xff00) {
+                       switch (size) {
+                       case 0xff00:
+                               rc = do_tuner_callback(fe, XC2028_RESET_CLK, 0);
+                               if (rc < 0) {
+                                       tuner_err("Error at RESET code %d\n",
+                                                 (*p) & 0x7f);
+                                       return -EINVAL;
+                               }
+                               break;
+                       default:
+                               tuner_info("Invalid RESET code %d\n",
+                                          size & 0x7f);
+                               return -EINVAL;
+
+                       }
+                       continue;
+               }
+
+               /* Checks for a sleep command */
+               if (size & 0x8000) {
+                       msleep(size & 0x7fff);
+                       continue;
+               }
+
+               if ((size + p > endp)) {
+                       tuner_err("missing bytes: need %d, have %d\n",
+                                  size, (int)(endp - p));
+                       return -EINVAL;
+               }
+
+               buf[0] = *p;
+               p++;
+               size--;
+
+               /* Sends message chunks */
+               while (size > 0) {
+                       int len = (size < priv->ctrl.max_len - 1) ?
+                                  size : priv->ctrl.max_len - 1;
+
+                       memcpy(buf + 1, p, len);
+
+                       rc = i2c_send(priv, buf, len + 1);
+                       if (rc < 0) {
+                               tuner_err("%d returned from send\n", rc);
+                               return -EINVAL;
+                       }
+
+                       p += len;
+                       size -= len;
+               }
+
+               /* silently fail if the frontend doesn't support I2C flush */
+               rc = do_tuner_callback(fe, XC2028_I2C_FLUSH, 0);
+               if ((rc < 0) && (rc != -EINVAL)) {
+                       tuner_err("error executing flush: %d\n", rc);
+                       return rc;
+               }
+       }
+       return 0;
+}
+
+static int load_scode(struct dvb_frontend *fe, unsigned int type,
+                        v4l2_std_id *id, __u16 int_freq, int scode)
+{
+       struct xc2028_data *priv = fe->tuner_priv;
+       int                pos, rc;
+       unsigned char      *p;
+
+       tuner_dbg("%s called\n", __func__);
+
+       if (!int_freq) {
+               pos = seek_firmware(fe, type, id);
+               if (pos < 0)
+                       return pos;
+       } else {
+               for (pos = 0; pos < priv->firm_size; pos++) {
+                       if ((priv->firm[pos].int_freq == int_freq) &&
+                           (priv->firm[pos].type & HAS_IF))
+                               break;
+               }
+               if (pos == priv->firm_size)
+                       return -ENOENT;
+       }
+
+       p = priv->firm[pos].ptr;
+
+       if (priv->firm[pos].type & HAS_IF) {
+               if (priv->firm[pos].size != 12 * 16 || scode >= 16)
+                       return -EINVAL;
+               p += 12 * scode;
+       } else {
+               /* 16 SCODE entries per file; each SCODE entry is 12 bytes and
+                * has a 2-byte size header in the firmware format. */
+               if (priv->firm[pos].size != 14 * 16 || scode >= 16 ||
+                   le16_to_cpu(*(__u16 *)(p + 14 * scode)) != 12)
+                       return -EINVAL;
+               p += 14 * scode + 2;
+       }
+
+       tuner_info("Loading SCODE for type=");
+       dump_firm_type_and_int_freq(priv->firm[pos].type,
+                                   priv->firm[pos].int_freq);
+       printk("(%x), id %016llx.\n", priv->firm[pos].type,
+              (unsigned long long)*id);
+
+       if (priv->firm_version < 0x0202)
+               rc = send_seq(priv, {0x20, 0x00, 0x00, 0x00});
+       else
+               rc = send_seq(priv, {0xa0, 0x00, 0x00, 0x00});
+       if (rc < 0)
+               return -EIO;
+
+       rc = i2c_send(priv, p, 12);
+       if (rc < 0)
+               return -EIO;
+
+       rc = send_seq(priv, {0x00, 0x8c});
+       if (rc < 0)
+               return -EIO;
+
+       return 0;
+}
+
+static int check_firmware(struct dvb_frontend *fe, unsigned int type,
+                         v4l2_std_id std, __u16 int_freq)
+{
+       struct xc2028_data         *priv = fe->tuner_priv;
+       struct firmware_properties new_fw;
+       int                        rc, retry_count = 0;
+       u16                        version, hwmodel;
+       v4l2_std_id                std0;
+
+       tuner_dbg("%s called\n", __func__);
+
+       rc = check_device_status(priv);
+       if (rc < 0)
+               return rc;
+
+       if (priv->ctrl.mts && !(type & FM))
+               type |= MTS;
+
+retry:
+       new_fw.type = type;
+       new_fw.id = std;
+       new_fw.std_req = std;
+       new_fw.scode_table = SCODE | priv->ctrl.scode_table;
+       new_fw.scode_nr = 0;
+       new_fw.int_freq = int_freq;
+
+       tuner_dbg("checking firmware, user requested type=");
+       if (debug) {
+               dump_firm_type(new_fw.type);
+               printk("(%x), id %016llx, ", new_fw.type,
+                      (unsigned long long)new_fw.std_req);
+               if (!int_freq) {
+                       printk("scode_tbl ");
+                       dump_firm_type(priv->ctrl.scode_table);
+                       printk("(%x), ", priv->ctrl.scode_table);
+               } else
+                       printk("int_freq %d, ", new_fw.int_freq);
+               printk("scode_nr %d\n", new_fw.scode_nr);
+       }
+
+       /*
+        * No need to reload base firmware if it matches and if the tuner
+        * is not at sleep mode
+        */
+       if ((priv->state == XC2028_ACTIVE) &&
+           (((BASE | new_fw.type) & BASE_TYPES) ==
+           (priv->cur_fw.type & BASE_TYPES))) {
+               tuner_dbg("BASE firmware not changed.\n");
+               goto skip_base;
+       }
+
+       /* Updating BASE - forget about all currently loaded firmware */
+       memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
+
+       /* Reset is needed before loading firmware */
+       rc = do_tuner_callback(fe, XC2028_TUNER_RESET, 0);
+       if (rc < 0)
+               goto fail;
+
+       /* BASE firmwares are all std0 */
+       std0 = 0;
+       rc = load_firmware(fe, BASE | new_fw.type, &std0);
+       if (rc < 0) {
+               tuner_err("Error %d while loading base firmware\n",
+                         rc);
+               goto fail;
+       }
+
+       /* Load INIT1, if needed */
+       tuner_dbg("Load init1 firmware, if exists\n");
+
+       rc = load_firmware(fe, BASE | INIT1 | new_fw.type, &std0);
+       if (rc == -ENOENT)
+               rc = load_firmware(fe, (BASE | INIT1 | new_fw.type) & ~F8MHZ,
+                                  &std0);
+       if (rc < 0 && rc != -ENOENT) {
+               tuner_err("Error %d while loading init1 firmware\n",
+                         rc);
+               goto fail;
+       }
+
+skip_base:
+       /*
+        * No need to reload standard specific firmware if base firmware
+        * was not reloaded and requested video standards have not changed.
+        */
+       if (priv->cur_fw.type == (BASE | new_fw.type) &&
+           priv->cur_fw.std_req == std) {
+               tuner_dbg("Std-specific firmware already loaded.\n");
+               goto skip_std_specific;
+       }
+
+       /* Reloading std-specific firmware forces a SCODE update */
+       priv->cur_fw.scode_table = 0;
+
+       rc = load_firmware(fe, new_fw.type, &new_fw.id);
+       if (rc == -ENOENT)
+               rc = load_firmware(fe, new_fw.type & ~F8MHZ, &new_fw.id);
+
+       if (rc < 0)
+               goto fail;
+
+skip_std_specific:
+       if (priv->cur_fw.scode_table == new_fw.scode_table &&
+           priv->cur_fw.scode_nr == new_fw.scode_nr) {
+               tuner_dbg("SCODE firmware already loaded.\n");
+               goto check_device;
+       }
+
+       if (new_fw.type & FM)
+               goto check_device;
+
+       /* Load SCODE firmware, if exists */
+       tuner_dbg("Trying to load scode %d\n", new_fw.scode_nr);
+
+       rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id,
+                       new_fw.int_freq, new_fw.scode_nr);
+
+check_device:
+       if (xc2028_get_reg(priv, 0x0004, &version) < 0 ||
+           xc2028_get_reg(priv, 0x0008, &hwmodel) < 0) {
+               tuner_err("Unable to read tuner registers.\n");
+               goto fail;
+       }
+
+       tuner_dbg("Device is Xceive %d version %d.%d, "
+                 "firmware version %d.%d\n",
+                 hwmodel, (version & 0xf000) >> 12, (version & 0xf00) >> 8,
+                 (version & 0xf0) >> 4, version & 0xf);
+
+
+       if (priv->ctrl.read_not_reliable)
+               goto read_not_reliable;
+
+       /* Check firmware version against what we downloaded. */
+       if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) {
+               if (!priv->ctrl.read_not_reliable) {
+                       tuner_err("Incorrect readback of firmware version.\n");
+                       goto fail;
+               } else {
+                       tuner_err("Returned an incorrect version. However, "
+                                 "read is not reliable enough. Ignoring it.\n");
+                       hwmodel = 3028;
+               }
+       }
+
+       /* Check that the tuner hardware model remains consistent over time. */
+       if (priv->hwmodel == 0 && (hwmodel == 2028 || hwmodel == 3028)) {
+               priv->hwmodel = hwmodel;
+               priv->hwvers  = version & 0xff00;
+       } else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel ||
+                  priv->hwvers != (version & 0xff00)) {
+               tuner_err("Read invalid device hardware information - tuner "
+                         "hung?\n");
+               goto fail;
+       }
+
+read_not_reliable:
+       memcpy(&priv->cur_fw, &new_fw, sizeof(priv->cur_fw));
+
+       /*
+        * By setting BASE in cur_fw.type only after successfully loading all
+        * firmwares, we can:
+        * 1. Identify that BASE firmware with type=0 has been loaded;
+        * 2. Tell whether BASE firmware was just changed the next time through.
+        */
+       priv->cur_fw.type |= BASE;
+       priv->state = XC2028_ACTIVE;
+
+       return 0;
+
+fail:
+       priv->state = XC2028_SLEEP;
+
+       memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
+       if (retry_count < 8) {
+               msleep(50);
+               retry_count++;
+               tuner_dbg("Retrying firmware load\n");
+               goto retry;
+       }
+
+       if (rc == -ENOENT)
+               rc = -EINVAL;
+       return rc;
+}
+
+static int xc2028_signal(struct dvb_frontend *fe, u16 *strength)
+{
+       struct xc2028_data *priv = fe->tuner_priv;
+       u16                 frq_lock, signal = 0;
+       int                 rc, i;
+
+       tuner_dbg("%s called\n", __func__);
+
+       rc = check_device_status(priv);
+       if (rc < 0)
+               return rc;
+
+       mutex_lock(&priv->lock);
+
+       /* Sync Lock Indicator */
+       for (i = 0; i < 3; i++) {
+               rc = xc2028_get_reg(priv, XREG_LOCK, &frq_lock);
+               if (rc < 0)
+                       goto ret;
+
+               if (frq_lock)
+                       break;
+               msleep(6);
+       }
+
+       /* Frequency didn't lock */
+       if (frq_lock == 2)
+               goto ret;
+
+       /* Get SNR of the video signal */
+       rc = xc2028_get_reg(priv, XREG_SNR, &signal);
+       if (rc < 0)
+               goto ret;
+
+       /* Signal level is 3 bits only */
+
+       signal = ((1 << 12) - 1) | ((signal & 0x07) << 12);
+
+ret:
+       mutex_unlock(&priv->lock);
+
+       *strength = signal;
+
+       tuner_dbg("signal strength is %d\n", signal);
+
+       return rc;
+}
+
+static int xc2028_get_afc(struct dvb_frontend *fe, s32 *afc)
+{
+       struct xc2028_data *priv = fe->tuner_priv;
+       int i, rc;
+       u16 frq_lock = 0;
+       s16 afc_reg = 0;
+
+       rc = check_device_status(priv);
+       if (rc < 0)
+               return rc;
+
+       mutex_lock(&priv->lock);
+
+       /* Sync Lock Indicator */
+       for (i = 0; i < 3; i++) {
+               rc = xc2028_get_reg(priv, XREG_LOCK, &frq_lock);
+               if (rc < 0)
+                       goto ret;
+
+               if (frq_lock)
+                       break;
+               msleep(6);
+       }
+
+       /* Frequency didn't lock */
+       if (frq_lock == 2)
+               goto ret;
+
+       /* Get AFC */
+       rc = xc2028_get_reg(priv, XREG_FREQ_ERROR, &afc_reg);
+       if (rc < 0)
+               goto ret;
+
+       *afc = afc_reg * 15625; /* Hz */
+
+       tuner_dbg("AFC is %d Hz\n", *afc);
+
+ret:
+       mutex_unlock(&priv->lock);
+
+       return rc;
+}
+
+#define DIV 15625
+
+static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
+                           enum v4l2_tuner_type new_type,
+                           unsigned int type,
+                           v4l2_std_id std,
+                           u16 int_freq)
+{
+       struct xc2028_data *priv = fe->tuner_priv;
+       int                rc = -EINVAL;
+       unsigned char      buf[4];
+       u32                div, offset = 0;
+
+       tuner_dbg("%s called\n", __func__);
+
+       mutex_lock(&priv->lock);
+
+       tuner_dbg("should set frequency %d kHz\n", freq / 1000);
+
+       if (check_firmware(fe, type, std, int_freq) < 0)
+               goto ret;
+
+       /* On some cases xc2028 can disable video output, if
+        * very weak signals are received. By sending a soft
+        * reset, this is re-enabled. So, it is better to always
+        * send a soft reset before changing channels, to be sure
+        * that xc2028 will be in a safe state.
+        * Maybe this might also be needed for DTV.
+        */
+       switch (new_type) {
+       case V4L2_TUNER_ANALOG_TV:
+               rc = send_seq(priv, {0x00, 0x00});
+
+               /* Analog mode requires offset = 0 */
+               break;
+       case V4L2_TUNER_RADIO:
+               /* Radio mode requires offset = 0 */
+               break;
+       case V4L2_TUNER_DIGITAL_TV:
+               /*
+                * Digital modes require an offset to adjust to the
+                * proper frequency. The offset depends on what
+                * firmware version is used.
+                */
+
+               /*
+                * Adjust to the center frequency. This is calculated by the
+                * formula: offset = 1.25MHz - BW/2
+                * For DTV 7/8, the firmware uses BW = 8000, so it needs a
+                * further adjustment to get the frequency center on VHF
+                */
+
+               /*
+                * The firmware DTV78 used to work fine in UHF band (8 MHz
+                * bandwidth) but not at all in VHF band (7 MHz bandwidth).
+                * The real problem was connected to the formula used to
+                * calculate the center frequency offset in VHF band.
+                * In fact, removing the 500KHz adjustment fixed the problem.
+                * This is coherent to what was implemented for the DTV7
+                * firmware.
+                * In the end, now the center frequency is the same for all 3
+                * firmwares (DTV7, DTV8, DTV78) and doesn't depend on channel
+                * bandwidth.
+                */
+
+               if (priv->cur_fw.type & DTV6)
+                       offset = 1750000;
+               else    /* DTV7 or DTV8 or DTV78 */
+                       offset = 2750000;
+
+               /*
+                * xc3028 additional "magic"
+                * Depending on the firmware version, it needs some adjustments
+                * to properly centralize the frequency. This seems to be
+                * needed to compensate the SCODE table adjustments made by
+                * newer firmwares
+                */
+
+               /*
+                * The proper adjustment would be to do it at s-code table.
+                * However, this didn't work, as reported by
+                * Robert Lowery <rglowery@exemail.com.au>
+                */
+
+#if 0
+               /*
+                * Still need tests for XC3028L (firmware 3.2 or upper)
+                * So, for now, let's just comment the per-firmware
+                * version of this change. Reports with xc3028l working
+                * with and without the lines bellow are welcome
+                */
+
+               if (priv->firm_version < 0x0302) {
+                       if (priv->cur_fw.type & DTV7)
+                               offset += 500000;
+               } else {
+                       if (priv->cur_fw.type & DTV7)
+                               offset -= 300000;
+                       else if (type != ATSC) /* DVB @6MHz, DTV 8 and DTV 7/8 */
+                               offset += 200000;
+               }
+#endif
+       }
+
+       div = (freq - offset + DIV / 2) / DIV;
+
+       /* CMD= Set frequency */
+       if (priv->firm_version < 0x0202)
+               rc = send_seq(priv, {0x00, XREG_RF_FREQ, 0x00, 0x00});
+       else
+               rc = send_seq(priv, {0x80, XREG_RF_FREQ, 0x00, 0x00});
+       if (rc < 0)
+               goto ret;
+
+       /* Return code shouldn't be checked.
+          The reset CLK is needed only with tm6000.
+          Driver should work fine even if this fails.
+        */
+       if (priv->ctrl.msleep)
+               msleep(priv->ctrl.msleep);
+       do_tuner_callback(fe, XC2028_RESET_CLK, 1);
+
+       msleep(10);
+
+       buf[0] = 0xff & (div >> 24);
+       buf[1] = 0xff & (div >> 16);
+       buf[2] = 0xff & (div >> 8);
+       buf[3] = 0xff & (div);
+
+       rc = i2c_send(priv, buf, sizeof(buf));
+       if (rc < 0)
+               goto ret;
+       msleep(100);
+
+       priv->frequency = freq;
+
+       tuner_dbg("divisor= %*ph (freq=%d.%03d)\n", 4, buf,
+              freq / 1000000, (freq % 1000000) / 1000);
+
+       rc = 0;
+
+ret:
+       mutex_unlock(&priv->lock);
+
+       return rc;
+}
+
+static int xc2028_set_analog_freq(struct dvb_frontend *fe,
+                             struct analog_parameters *p)
+{
+       struct xc2028_data *priv = fe->tuner_priv;
+       unsigned int       type=0;
+
+       tuner_dbg("%s called\n", __func__);
+
+       if (p->mode == V4L2_TUNER_RADIO) {
+               type |= FM;
+               if (priv->ctrl.input1)
+                       type |= INPUT1;
+               return generic_set_freq(fe, (625l * p->frequency) / 10,
+                               V4L2_TUNER_RADIO, type, 0, 0);
+       }
+
+       /* if std is not defined, choose one */
+       if (!p->std)
+               p->std = V4L2_STD_MN;
+
+       /* PAL/M, PAL/N, PAL/Nc and NTSC variants should use 6MHz firmware */
+       if (!(p->std & V4L2_STD_MN))
+               type |= F8MHZ;
+
+       /* Add audio hack to std mask */
+       p->std |= parse_audio_std_option();
+
+       return generic_set_freq(fe, 62500l * p->frequency,
+                               V4L2_TUNER_ANALOG_TV, type, p->std, 0);
+}
+
+static int xc2028_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u32 delsys = c->delivery_system;
+       u32 bw = c->bandwidth_hz;
+       struct xc2028_data *priv = fe->tuner_priv;
+       int rc;
+       unsigned int       type = 0;
+       u16                demod = 0;
+
+       tuner_dbg("%s called\n", __func__);
+
+       rc = check_device_status(priv);
+       if (rc < 0)
+               return rc;
+
+       switch (delsys) {
+       case SYS_DVBT:
+       case SYS_DVBT2:
+               /*
+                * The only countries with 6MHz seem to be Taiwan/Uruguay.
+                * Both seem to require QAM firmware for OFDM decoding
+                * Tested in Taiwan by Terry Wu <terrywu2009@gmail.com>
+                */
+               if (bw <= 6000000)
+                       type |= QAM;
+
+               switch (priv->ctrl.type) {
+               case XC2028_D2633:
+                       type |= D2633;
+                       break;
+               case XC2028_D2620:
+                       type |= D2620;
+                       break;
+               case XC2028_AUTO:
+               default:
+                       /* Zarlink seems to need D2633 */
+                       if (priv->ctrl.demod == XC3028_FE_ZARLINK456)
+                               type |= D2633;
+                       else
+                               type |= D2620;
+               }
+               break;
+       case SYS_ATSC:
+               /* The only ATSC firmware (at least on v2.7) is D2633 */
+               type |= ATSC | D2633;
+               break;
+       /* DVB-S and pure QAM (FE_QAM) are not supported */
+       default:
+               return -EINVAL;
+       }
+
+       if (bw <= 6000000) {
+               type |= DTV6;
+               priv->ctrl.vhfbw7 = 0;
+               priv->ctrl.uhfbw8 = 0;
+       } else if (bw <= 7000000) {
+               if (c->frequency < 470000000)
+                       priv->ctrl.vhfbw7 = 1;
+               else
+                       priv->ctrl.uhfbw8 = 0;
+               type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV7;
+               type |= F8MHZ;
+       } else {
+               if (c->frequency < 470000000)
+                       priv->ctrl.vhfbw7 = 0;
+               else
+                       priv->ctrl.uhfbw8 = 1;
+               type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV8;
+               type |= F8MHZ;
+       }
+
+       /* All S-code tables need a 200kHz shift */
+       if (priv->ctrl.demod) {
+               demod = priv->ctrl.demod;
+
+               /*
+                * Newer firmwares require a 200 kHz offset only for ATSC
+                */
+               if (type == ATSC || priv->firm_version < 0x0302)
+                       demod += 200;
+               /*
+                * The DTV7 S-code table needs a 700 kHz shift.
+                *
+                * DTV7 is only used in Australia.  Germany or Italy may also
+                * use this firmware after initialization, but a tune to a UHF
+                * channel should then cause DTV78 to be used.
+                *
+                * Unfortunately, on real-field tests, the s-code offset
+                * didn't work as expected, as reported by
+                * Robert Lowery <rglowery@exemail.com.au>
+                */
+       }
+
+       return generic_set_freq(fe, c->frequency,
+                               V4L2_TUNER_DIGITAL_TV, type, 0, demod);
+}
+
+static int xc2028_sleep(struct dvb_frontend *fe)
+{
+       struct xc2028_data *priv = fe->tuner_priv;
+       int rc;
+
+       rc = check_device_status(priv);
+       if (rc < 0)
+               return rc;
+
+       /* Avoid firmware reload on slow devices or if PM disabled */
+       if (no_poweroff || priv->ctrl.disable_power_mgmt)
+               return 0;
+
+       tuner_dbg("Putting xc2028/3028 into poweroff mode.\n");
+       if (debug > 1) {
+               tuner_dbg("Printing sleep stack trace:\n");
+               dump_stack();
+       }
+
+       mutex_lock(&priv->lock);
+
+       if (priv->firm_version < 0x0202)
+               rc = send_seq(priv, {0x00, XREG_POWER_DOWN, 0x00, 0x00});
+       else
+               rc = send_seq(priv, {0x80, XREG_POWER_DOWN, 0x00, 0x00});
+
+       priv->state = XC2028_SLEEP;
+
+       mutex_unlock(&priv->lock);
+
+       return rc;
+}
+
+static int xc2028_dvb_release(struct dvb_frontend *fe)
+{
+       struct xc2028_data *priv = fe->tuner_priv;
+
+       tuner_dbg("%s called\n", __func__);
+
+       mutex_lock(&xc2028_list_mutex);
+
+       /* only perform final cleanup if this is the last instance */
+       if (hybrid_tuner_report_instance_count(priv) == 1) {
+               free_firmware(priv);
+               kfree(priv->ctrl.fname);
+               priv->ctrl.fname = NULL;
+       }
+
+       if (priv)
+               hybrid_tuner_release_state(priv);
+
+       mutex_unlock(&xc2028_list_mutex);
+
+       fe->tuner_priv = NULL;
+
+       return 0;
+}
+
+static int xc2028_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct xc2028_data *priv = fe->tuner_priv;
+       int rc;
+
+       tuner_dbg("%s called\n", __func__);
+
+       rc = check_device_status(priv);
+       if (rc < 0)
+               return rc;
+
+       *frequency = priv->frequency;
+
+       return 0;
+}
+
+static void load_firmware_cb(const struct firmware *fw,
+                            void *context)
+{
+       struct dvb_frontend *fe = context;
+       struct xc2028_data *priv = fe->tuner_priv;
+       int rc;
+
+       tuner_dbg("request_firmware_nowait(): %s\n", fw ? "OK" : "error");
+       if (!fw) {
+               tuner_err("Could not load firmware %s.\n", priv->fname);
+               priv->state = XC2028_NODEV;
+               return;
+       }
+
+       rc = load_all_firmwares(fe, fw);
+
+       release_firmware(fw);
+
+       if (rc < 0)
+               return;
+       priv->state = XC2028_SLEEP;
+}
+
+static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
+{
+       struct xc2028_data *priv = fe->tuner_priv;
+       struct xc2028_ctrl *p    = priv_cfg;
+       int                 rc   = 0;
+
+       tuner_dbg("%s called\n", __func__);
+
+       mutex_lock(&priv->lock);
+
+       /*
+        * Copy the config data.
+        * For the firmware name, keep a local copy of the string,
+        * in order to avoid troubles during device release.
+        */
+       if (priv->ctrl.fname)
+               kfree(priv->ctrl.fname);
+       memcpy(&priv->ctrl, p, sizeof(priv->ctrl));
+       if (p->fname) {
+               priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL);
+               if (priv->ctrl.fname == NULL)
+                       rc = -ENOMEM;
+       }
+
+       /*
+        * If firmware name changed, frees firmware. As free_firmware will
+        * reset the status to NO_FIRMWARE, this forces a new request_firmware
+        */
+       if (!firmware_name[0] && p->fname &&
+           priv->fname && strcmp(p->fname, priv->fname))
+               free_firmware(priv);
+
+       if (priv->ctrl.max_len < 9)
+               priv->ctrl.max_len = 13;
+
+       if (priv->state == XC2028_NO_FIRMWARE) {
+               if (!firmware_name[0])
+                       priv->fname = priv->ctrl.fname;
+               else
+                       priv->fname = firmware_name;
+
+               rc = request_firmware_nowait(THIS_MODULE, 1,
+                                            priv->fname,
+                                            priv->i2c_props.adap->dev.parent,
+                                            GFP_KERNEL,
+                                            fe, load_firmware_cb);
+               if (rc < 0) {
+                       tuner_err("Failed to request firmware %s\n",
+                                 priv->fname);
+                       priv->state = XC2028_NODEV;
+               } else
+                       priv->state = XC2028_WAITING_FIRMWARE;
+       }
+       mutex_unlock(&priv->lock);
+
+       return rc;
+}
+
+static const struct dvb_tuner_ops xc2028_dvb_tuner_ops = {
+       .info = {
+                .name = "Xceive XC3028",
+                .frequency_min = 42000000,
+                .frequency_max = 864000000,
+                .frequency_step = 50000,
+                },
+
+       .set_config        = xc2028_set_config,
+       .set_analog_params = xc2028_set_analog_freq,
+       .release           = xc2028_dvb_release,
+       .get_frequency     = xc2028_get_frequency,
+       .get_rf_strength   = xc2028_signal,
+       .get_afc           = xc2028_get_afc,
+       .set_params        = xc2028_set_params,
+       .sleep             = xc2028_sleep,
+};
+
+struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
+                                  struct xc2028_config *cfg)
+{
+       struct xc2028_data *priv;
+       int instance;
+
+       if (debug)
+               printk(KERN_DEBUG "xc2028: Xcv2028/3028 init called!\n");
+
+       if (NULL == cfg)
+               return NULL;
+
+       if (!fe) {
+               printk(KERN_ERR "xc2028: No frontend!\n");
+               return NULL;
+       }
+
+       mutex_lock(&xc2028_list_mutex);
+
+       instance = hybrid_tuner_request_state(struct xc2028_data, priv,
+                                             hybrid_tuner_instance_list,
+                                             cfg->i2c_adap, cfg->i2c_addr,
+                                             "xc2028");
+       switch (instance) {
+       case 0:
+               /* memory allocation failure */
+               goto fail;
+               break;
+       case 1:
+               /* new tuner instance */
+               priv->ctrl.max_len = 13;
+
+               mutex_init(&priv->lock);
+
+               fe->tuner_priv = priv;
+               break;
+       case 2:
+               /* existing tuner instance */
+               fe->tuner_priv = priv;
+               break;
+       }
+
+       memcpy(&fe->ops.tuner_ops, &xc2028_dvb_tuner_ops,
+              sizeof(xc2028_dvb_tuner_ops));
+
+       tuner_info("type set to %s\n", "XCeive xc2028/xc3028 tuner");
+
+       if (cfg->ctrl)
+               xc2028_set_config(fe, cfg->ctrl);
+
+       mutex_unlock(&xc2028_list_mutex);
+
+       return fe;
+fail:
+       mutex_unlock(&xc2028_list_mutex);
+
+       xc2028_dvb_release(fe);
+       return NULL;
+}
+
+EXPORT_SYMBOL(xc2028_attach);
+
+MODULE_DESCRIPTION("Xceive xc2028/xc3028 tuner driver");
+MODULE_AUTHOR("Michel Ludwig <michel.ludwig@gmail.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
+MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(XC2028_DEFAULT_FIRMWARE);
+MODULE_FIRMWARE(XC3028L_DEFAULT_FIRMWARE);
diff --git a/drivers/media/tuners/tuner-xc2028.h b/drivers/media/tuners/tuner-xc2028.h
new file mode 100644 (file)
index 0000000..9ebfb2d
--- /dev/null
@@ -0,0 +1,72 @@
+/* tuner-xc2028
+ *
+ * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
+ * This code is placed under the terms of the GNU General Public License v2
+ */
+
+#ifndef __TUNER_XC2028_H__
+#define __TUNER_XC2028_H__
+
+#include "dvb_frontend.h"
+
+#define XC2028_DEFAULT_FIRMWARE "xc3028-v27.fw"
+#define XC3028L_DEFAULT_FIRMWARE "xc3028L-v36.fw"
+
+/*      Dmoduler               IF (kHz) */
+#define        XC3028_FE_DEFAULT       0               /* Don't load SCODE */
+#define XC3028_FE_LG60         6000
+#define        XC3028_FE_ATI638        6380
+#define        XC3028_FE_OREN538       5380
+#define        XC3028_FE_OREN36        3600
+#define        XC3028_FE_TOYOTA388     3880
+#define        XC3028_FE_TOYOTA794     7940
+#define        XC3028_FE_DIBCOM52      5200
+#define        XC3028_FE_ZARLINK456    4560
+#define        XC3028_FE_CHINA         5200
+
+enum firmware_type {
+       XC2028_AUTO = 0,        /* By default, auto-detects */
+       XC2028_D2633,
+       XC2028_D2620,
+};
+
+struct xc2028_ctrl {
+       char                    *fname;
+       int                     max_len;
+       int                     msleep;
+       unsigned int            scode_table;
+       unsigned int            mts   :1;
+       unsigned int            input1:1;
+       unsigned int            vhfbw7:1;
+       unsigned int            uhfbw8:1;
+       unsigned int            disable_power_mgmt:1;
+       unsigned int            read_not_reliable:1;
+       unsigned int            demod;
+       enum firmware_type      type:2;
+};
+
+struct xc2028_config {
+       struct i2c_adapter *i2c_adap;
+       u8                 i2c_addr;
+       struct xc2028_ctrl *ctrl;
+};
+
+/* xc2028 commands for callback */
+#define XC2028_TUNER_RESET     0
+#define XC2028_RESET_CLK       1
+#define XC2028_I2C_FLUSH       2
+
+#if defined(CONFIG_MEDIA_TUNER_XC2028) || (defined(CONFIG_MEDIA_TUNER_XC2028_MODULE) && defined(MODULE))
+extern struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
+                                         struct xc2028_config *cfg);
+#else
+static inline struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
+                                                struct xc2028_config *cfg)
+{
+       printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
+              __func__);
+       return NULL;
+}
+#endif
+
+#endif /* __TUNER_XC2028_H__ */
diff --git a/drivers/media/tuners/xc4000.c b/drivers/media/tuners/xc4000.c
new file mode 100644 (file)
index 0000000..4937712
--- /dev/null
@@ -0,0 +1,1757 @@
+/*
+ *  Driver for Xceive XC4000 "QAM/8VSB single chip tuner"
+ *
+ *  Copyright (c) 2007 Xceive Corporation
+ *  Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
+ *  Copyright (c) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
+ *  Copyright (c) 2009 Davide Ferri <d.ferri@zero11.it>
+ *  Copyright (c) 2010 Istvan Varga <istvan_v@mailbox.hu>
+ *
+ *  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.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/videodev2.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <asm/unaligned.h>
+
+#include "dvb_frontend.h"
+
+#include "xc4000.h"
+#include "tuner-i2c.h"
+#include "tuner-xc2028-types.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debugging level (0 to 2, default: 0 (off)).");
+
+static int no_poweroff;
+module_param(no_poweroff, int, 0644);
+MODULE_PARM_DESC(no_poweroff, "Power management (1: disabled, 2: enabled, "
+       "0 (default): use device-specific default mode).");
+
+static int audio_std;
+module_param(audio_std, int, 0644);
+MODULE_PARM_DESC(audio_std, "Audio standard. XC4000 audio decoder explicitly "
+       "needs to know what audio standard is needed for some video standards "
+       "with audio A2 or NICAM. The valid settings are a sum of:\n"
+       " 1: use NICAM/B or A2/B instead of NICAM/A or A2/A\n"
+       " 2: use A2 instead of NICAM or BTSC\n"
+       " 4: use SECAM/K3 instead of K1\n"
+       " 8: use PAL-D/K audio for SECAM-D/K\n"
+       "16: use FM radio input 1 instead of input 2\n"
+       "32: use mono audio (the lower three bits are ignored)");
+
+static char firmware_name[30];
+module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0);
+MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the "
+       "default firmware name.");
+
+static DEFINE_MUTEX(xc4000_list_mutex);
+static LIST_HEAD(hybrid_tuner_instance_list);
+
+#define dprintk(level, fmt, arg...) if (debug >= level) \
+       printk(KERN_INFO "%s: " fmt, "xc4000", ## arg)
+
+/* struct for storing firmware table */
+struct firmware_description {
+       unsigned int  type;
+       v4l2_std_id   id;
+       __u16         int_freq;
+       unsigned char *ptr;
+       unsigned int  size;
+};
+
+struct firmware_properties {
+       unsigned int    type;
+       v4l2_std_id     id;
+       v4l2_std_id     std_req;
+       __u16           int_freq;
+       unsigned int    scode_table;
+       int             scode_nr;
+};
+
+struct xc4000_priv {
+       struct tuner_i2c_props i2c_props;
+       struct list_head hybrid_tuner_instance_list;
+       struct firmware_description *firm;
+       int     firm_size;
+       u32     if_khz;
+       u32     freq_hz;
+       u32     bandwidth;
+       u8      video_standard;
+       u8      rf_mode;
+       u8      default_pm;
+       u8      dvb_amplitude;
+       u8      set_smoothedcvbs;
+       u8      ignore_i2c_write_errors;
+       __u16   firm_version;
+       struct firmware_properties cur_fw;
+       __u16   hwmodel;
+       __u16   hwvers;
+       struct mutex    lock;
+};
+
+#define XC4000_AUDIO_STD_B              1
+#define XC4000_AUDIO_STD_A2             2
+#define XC4000_AUDIO_STD_K3             4
+#define XC4000_AUDIO_STD_L              8
+#define XC4000_AUDIO_STD_INPUT1                16
+#define XC4000_AUDIO_STD_MONO          32
+
+#define XC4000_DEFAULT_FIRMWARE "dvb-fe-xc4000-1.4.fw"
+
+/* Misc Defines */
+#define MAX_TV_STANDARD                        24
+#define XC_MAX_I2C_WRITE_LENGTH                64
+#define XC_POWERED_DOWN                        0x80000000U
+
+/* Signal Types */
+#define XC_RF_MODE_AIR                 0
+#define XC_RF_MODE_CABLE               1
+
+/* Product id */
+#define XC_PRODUCT_ID_FW_NOT_LOADED    0x2000
+#define XC_PRODUCT_ID_XC4000           0x0FA0
+#define XC_PRODUCT_ID_XC4100           0x1004
+
+/* Registers (Write-only) */
+#define XREG_INIT         0x00
+#define XREG_VIDEO_MODE   0x01
+#define XREG_AUDIO_MODE   0x02
+#define XREG_RF_FREQ      0x03
+#define XREG_D_CODE       0x04
+#define XREG_DIRECTSITTING_MODE 0x05
+#define XREG_SEEK_MODE    0x06
+#define XREG_POWER_DOWN   0x08
+#define XREG_SIGNALSOURCE 0x0A
+#define XREG_SMOOTHEDCVBS 0x0E
+#define XREG_AMPLITUDE    0x10
+
+/* Registers (Read-only) */
+#define XREG_ADC_ENV      0x00
+#define XREG_QUALITY      0x01
+#define XREG_FRAME_LINES  0x02
+#define XREG_HSYNC_FREQ   0x03
+#define XREG_LOCK         0x04
+#define XREG_FREQ_ERROR   0x05
+#define XREG_SNR          0x06
+#define XREG_VERSION      0x07
+#define XREG_PRODUCT_ID   0x08
+#define XREG_SIGNAL_LEVEL 0x0A
+#define XREG_NOISE_LEVEL  0x0B
+
+/*
+   Basic firmware description. This will remain with
+   the driver for documentation purposes.
+
+   This represents an I2C firmware file encoded as a
+   string of unsigned char. Format is as follows:
+
+   char[0  ]=len0_MSB  -> len = len_MSB * 256 + len_LSB
+   char[1  ]=len0_LSB  -> length of first write transaction
+   char[2  ]=data0 -> first byte to be sent
+   char[3  ]=data1
+   char[4  ]=data2
+   char[   ]=...
+   char[M  ]=dataN  -> last byte to be sent
+   char[M+1]=len1_MSB  -> len = len_MSB * 256 + len_LSB
+   char[M+2]=len1_LSB  -> length of second write transaction
+   char[M+3]=data0
+   char[M+4]=data1
+   ...
+   etc.
+
+   The [len] value should be interpreted as follows:
+
+   len= len_MSB _ len_LSB
+   len=1111_1111_1111_1111   : End of I2C_SEQUENCE
+   len=0000_0000_0000_0000   : Reset command: Do hardware reset
+   len=0NNN_NNNN_NNNN_NNNN   : Normal transaction: number of bytes = {1:32767)
+   len=1WWW_WWWW_WWWW_WWWW   : Wait command: wait for {1:32767} ms
+
+   For the RESET and WAIT commands, the two following bytes will contain
+   immediately the length of the following transaction.
+*/
+
+struct XC_TV_STANDARD {
+       const char  *Name;
+       u16         audio_mode;
+       u16         video_mode;
+       u16         int_freq;
+};
+
+/* Tuner standards */
+#define XC4000_MN_NTSC_PAL_BTSC                0
+#define XC4000_MN_NTSC_PAL_A2          1
+#define XC4000_MN_NTSC_PAL_EIAJ                2
+#define XC4000_MN_NTSC_PAL_Mono                3
+#define XC4000_BG_PAL_A2               4
+#define XC4000_BG_PAL_NICAM            5
+#define XC4000_BG_PAL_MONO             6
+#define XC4000_I_PAL_NICAM             7
+#define XC4000_I_PAL_NICAM_MONO                8
+#define XC4000_DK_PAL_A2               9
+#define XC4000_DK_PAL_NICAM            10
+#define XC4000_DK_PAL_MONO             11
+#define XC4000_DK_SECAM_A2DK1          12
+#define XC4000_DK_SECAM_A2LDK3         13
+#define XC4000_DK_SECAM_A2MONO         14
+#define XC4000_DK_SECAM_NICAM          15
+#define XC4000_L_SECAM_NICAM           16
+#define XC4000_LC_SECAM_NICAM          17
+#define XC4000_DTV6                    18
+#define XC4000_DTV8                    19
+#define XC4000_DTV7_8                  20
+#define XC4000_DTV7                    21
+#define XC4000_FM_Radio_INPUT2         22
+#define XC4000_FM_Radio_INPUT1         23
+
+static struct XC_TV_STANDARD xc4000_standard[MAX_TV_STANDARD] = {
+       {"M/N-NTSC/PAL-BTSC",   0x0000, 0x80A0, 4500},
+       {"M/N-NTSC/PAL-A2",     0x0000, 0x80A0, 4600},
+       {"M/N-NTSC/PAL-EIAJ",   0x0040, 0x80A0, 4500},
+       {"M/N-NTSC/PAL-Mono",   0x0078, 0x80A0, 4500},
+       {"B/G-PAL-A2",          0x0000, 0x8159, 5640},
+       {"B/G-PAL-NICAM",       0x0004, 0x8159, 5740},
+       {"B/G-PAL-MONO",        0x0078, 0x8159, 5500},
+       {"I-PAL-NICAM",         0x0080, 0x8049, 6240},
+       {"I-PAL-NICAM-MONO",    0x0078, 0x8049, 6000},
+       {"D/K-PAL-A2",          0x0000, 0x8049, 6380},
+       {"D/K-PAL-NICAM",       0x0080, 0x8049, 6200},
+       {"D/K-PAL-MONO",        0x0078, 0x8049, 6500},
+       {"D/K-SECAM-A2 DK1",    0x0000, 0x8049, 6340},
+       {"D/K-SECAM-A2 L/DK3",  0x0000, 0x8049, 6000},
+       {"D/K-SECAM-A2 MONO",   0x0078, 0x8049, 6500},
+       {"D/K-SECAM-NICAM",     0x0080, 0x8049, 6200},
+       {"L-SECAM-NICAM",       0x8080, 0x0009, 6200},
+       {"L'-SECAM-NICAM",      0x8080, 0x4009, 6200},
+       {"DTV6",                0x00C0, 0x8002,    0},
+       {"DTV8",                0x00C0, 0x800B,    0},
+       {"DTV7/8",              0x00C0, 0x801B,    0},
+       {"DTV7",                0x00C0, 0x8007,    0},
+       {"FM Radio-INPUT2",     0x0008, 0x9800, 10700},
+       {"FM Radio-INPUT1",     0x0008, 0x9000, 10700}
+};
+
+static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val);
+static int xc4000_tuner_reset(struct dvb_frontend *fe);
+static void xc_debug_dump(struct xc4000_priv *priv);
+
+static int xc_send_i2c_data(struct xc4000_priv *priv, u8 *buf, int len)
+{
+       struct i2c_msg msg = { .addr = priv->i2c_props.addr,
+                              .flags = 0, .buf = buf, .len = len };
+       if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
+               if (priv->ignore_i2c_write_errors == 0) {
+                       printk(KERN_ERR "xc4000: I2C write failed (len=%i)\n",
+                              len);
+                       if (len == 4) {
+                               printk(KERN_ERR "bytes %*ph\n", 4, buf);
+                       }
+                       return -EREMOTEIO;
+               }
+       }
+       return 0;
+}
+
+static int xc4000_tuner_reset(struct dvb_frontend *fe)
+{
+       struct xc4000_priv *priv = fe->tuner_priv;
+       int ret;
+
+       dprintk(1, "%s()\n", __func__);
+
+       if (fe->callback) {
+               ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
+                                          fe->dvb->priv :
+                                          priv->i2c_props.adap->algo_data,
+                                          DVB_FRONTEND_COMPONENT_TUNER,
+                                          XC4000_TUNER_RESET, 0);
+               if (ret) {
+                       printk(KERN_ERR "xc4000: reset failed\n");
+                       return -EREMOTEIO;
+               }
+       } else {
+               printk(KERN_ERR "xc4000: no tuner reset callback function, "
+                               "fatal\n");
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int xc_write_reg(struct xc4000_priv *priv, u16 regAddr, u16 i2cData)
+{
+       u8 buf[4];
+       int result;
+
+       buf[0] = (regAddr >> 8) & 0xFF;
+       buf[1] = regAddr & 0xFF;
+       buf[2] = (i2cData >> 8) & 0xFF;
+       buf[3] = i2cData & 0xFF;
+       result = xc_send_i2c_data(priv, buf, 4);
+
+       return result;
+}
+
+static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
+{
+       struct xc4000_priv *priv = fe->tuner_priv;
+
+       int i, nbytes_to_send, result;
+       unsigned int len, pos, index;
+       u8 buf[XC_MAX_I2C_WRITE_LENGTH];
+
+       index = 0;
+       while ((i2c_sequence[index] != 0xFF) ||
+               (i2c_sequence[index + 1] != 0xFF)) {
+               len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
+               if (len == 0x0000) {
+                       /* RESET command */
+                       /* NOTE: this is ignored, as the reset callback was */
+                       /* already called by check_firmware() */
+                       index += 2;
+               } else if (len & 0x8000) {
+                       /* WAIT command */
+                       msleep(len & 0x7FFF);
+                       index += 2;
+               } else {
+                       /* Send i2c data whilst ensuring individual transactions
+                        * do not exceed XC_MAX_I2C_WRITE_LENGTH bytes.
+                        */
+                       index += 2;
+                       buf[0] = i2c_sequence[index];
+                       buf[1] = i2c_sequence[index + 1];
+                       pos = 2;
+                       while (pos < len) {
+                               if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
+                                       nbytes_to_send =
+                                               XC_MAX_I2C_WRITE_LENGTH;
+                               else
+                                       nbytes_to_send = (len - pos + 2);
+                               for (i = 2; i < nbytes_to_send; i++) {
+                                       buf[i] = i2c_sequence[index + pos +
+                                               i - 2];
+                               }
+                               result = xc_send_i2c_data(priv, buf,
+                                       nbytes_to_send);
+
+                               if (result != 0)
+                                       return result;
+
+                               pos += nbytes_to_send - 2;
+                       }
+                       index += len;
+               }
+       }
+       return 0;
+}
+
+static int xc_set_tv_standard(struct xc4000_priv *priv,
+       u16 video_mode, u16 audio_mode)
+{
+       int ret;
+       dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, video_mode, audio_mode);
+       dprintk(1, "%s() Standard = %s\n",
+               __func__,
+               xc4000_standard[priv->video_standard].Name);
+
+       /* Don't complain when the request fails because of i2c stretching */
+       priv->ignore_i2c_write_errors = 1;
+
+       ret = xc_write_reg(priv, XREG_VIDEO_MODE, video_mode);
+       if (ret == 0)
+               ret = xc_write_reg(priv, XREG_AUDIO_MODE, audio_mode);
+
+       priv->ignore_i2c_write_errors = 0;
+
+       return ret;
+}
+
+static int xc_set_signal_source(struct xc4000_priv *priv, u16 rf_mode)
+{
+       dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
+               rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
+
+       if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
+               rf_mode = XC_RF_MODE_CABLE;
+               printk(KERN_ERR
+                       "%s(), Invalid mode, defaulting to CABLE",
+                       __func__);
+       }
+       return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
+}
+
+static const struct dvb_tuner_ops xc4000_tuner_ops;
+
+static int xc_set_rf_frequency(struct xc4000_priv *priv, u32 freq_hz)
+{
+       u16 freq_code;
+
+       dprintk(1, "%s(%u)\n", __func__, freq_hz);
+
+       if ((freq_hz > xc4000_tuner_ops.info.frequency_max) ||
+           (freq_hz < xc4000_tuner_ops.info.frequency_min))
+               return -EINVAL;
+
+       freq_code = (u16)(freq_hz / 15625);
+
+       /* WAS: Starting in firmware version 1.1.44, Xceive recommends using the
+          FINERFREQ for all normal tuning (the doc indicates reg 0x03 should
+          only be used for fast scanning for channel lock) */
+       /* WAS: XREG_FINERFREQ */
+       return xc_write_reg(priv, XREG_RF_FREQ, freq_code);
+}
+
+static int xc_get_adc_envelope(struct xc4000_priv *priv, u16 *adc_envelope)
+{
+       return xc4000_readreg(priv, XREG_ADC_ENV, adc_envelope);
+}
+
+static int xc_get_frequency_error(struct xc4000_priv *priv, u32 *freq_error_hz)
+{
+       int result;
+       u16 regData;
+       u32 tmp;
+
+       result = xc4000_readreg(priv, XREG_FREQ_ERROR, &regData);
+       if (result != 0)
+               return result;
+
+       tmp = (u32)regData & 0xFFFFU;
+       tmp = (tmp < 0x8000U ? tmp : 0x10000U - tmp);
+       (*freq_error_hz) = tmp * 15625;
+       return result;
+}
+
+static int xc_get_lock_status(struct xc4000_priv *priv, u16 *lock_status)
+{
+       return xc4000_readreg(priv, XREG_LOCK, lock_status);
+}
+
+static int xc_get_version(struct xc4000_priv *priv,
+       u8 *hw_majorversion, u8 *hw_minorversion,
+       u8 *fw_majorversion, u8 *fw_minorversion)
+{
+       u16 data;
+       int result;
+
+       result = xc4000_readreg(priv, XREG_VERSION, &data);
+       if (result != 0)
+               return result;
+
+       (*hw_majorversion) = (data >> 12) & 0x0F;
+       (*hw_minorversion) = (data >>  8) & 0x0F;
+       (*fw_majorversion) = (data >>  4) & 0x0F;
+       (*fw_minorversion) = data & 0x0F;
+
+       return 0;
+}
+
+static int xc_get_hsync_freq(struct xc4000_priv *priv, u32 *hsync_freq_hz)
+{
+       u16 regData;
+       int result;
+
+       result = xc4000_readreg(priv, XREG_HSYNC_FREQ, &regData);
+       if (result != 0)
+               return result;
+
+       (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
+       return result;
+}
+
+static int xc_get_frame_lines(struct xc4000_priv *priv, u16 *frame_lines)
+{
+       return xc4000_readreg(priv, XREG_FRAME_LINES, frame_lines);
+}
+
+static int xc_get_quality(struct xc4000_priv *priv, u16 *quality)
+{
+       return xc4000_readreg(priv, XREG_QUALITY, quality);
+}
+
+static int xc_get_signal_level(struct xc4000_priv *priv, u16 *signal)
+{
+       return xc4000_readreg(priv, XREG_SIGNAL_LEVEL, signal);
+}
+
+static int xc_get_noise_level(struct xc4000_priv *priv, u16 *noise)
+{
+       return xc4000_readreg(priv, XREG_NOISE_LEVEL, noise);
+}
+
+static u16 xc_wait_for_lock(struct xc4000_priv *priv)
+{
+       u16     lock_state = 0;
+       int     watchdog_count = 40;
+
+       while ((lock_state == 0) && (watchdog_count > 0)) {
+               xc_get_lock_status(priv, &lock_state);
+               if (lock_state != 1) {
+                       msleep(5);
+                       watchdog_count--;
+               }
+       }
+       return lock_state;
+}
+
+static int xc_tune_channel(struct xc4000_priv *priv, u32 freq_hz)
+{
+       int     found = 1;
+       int     result;
+
+       dprintk(1, "%s(%u)\n", __func__, freq_hz);
+
+       /* Don't complain when the request fails because of i2c stretching */
+       priv->ignore_i2c_write_errors = 1;
+       result = xc_set_rf_frequency(priv, freq_hz);
+       priv->ignore_i2c_write_errors = 0;
+
+       if (result != 0)
+               return 0;
+
+       /* wait for lock only in analog TV mode */
+       if ((priv->cur_fw.type & (FM | DTV6 | DTV7 | DTV78 | DTV8)) == 0) {
+               if (xc_wait_for_lock(priv) != 1)
+                       found = 0;
+       }
+
+       /* Wait for stats to stabilize.
+        * Frame Lines needs two frame times after initial lock
+        * before it is valid.
+        */
+       msleep(debug ? 100 : 10);
+
+       if (debug)
+               xc_debug_dump(priv);
+
+       return found;
+}
+
+static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val)
+{
+       u8 buf[2] = { reg >> 8, reg & 0xff };
+       u8 bval[2] = { 0, 0 };
+       struct i2c_msg msg[2] = {
+               { .addr = priv->i2c_props.addr,
+                       .flags = 0, .buf = &buf[0], .len = 2 },
+               { .addr = priv->i2c_props.addr,
+                       .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
+       };
+
+       if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
+               printk(KERN_ERR "xc4000: I2C read failed\n");
+               return -EREMOTEIO;
+       }
+
+       *val = (bval[0] << 8) | bval[1];
+       return 0;
+}
+
+#define dump_firm_type(t)      dump_firm_type_and_int_freq(t, 0)
+static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
+{
+        if (type & BASE)
+               printk(KERN_CONT "BASE ");
+        if (type & INIT1)
+               printk(KERN_CONT "INIT1 ");
+        if (type & F8MHZ)
+               printk(KERN_CONT "F8MHZ ");
+        if (type & MTS)
+               printk(KERN_CONT "MTS ");
+        if (type & D2620)
+               printk(KERN_CONT "D2620 ");
+        if (type & D2633)
+               printk(KERN_CONT "D2633 ");
+        if (type & DTV6)
+               printk(KERN_CONT "DTV6 ");
+        if (type & QAM)
+               printk(KERN_CONT "QAM ");
+        if (type & DTV7)
+               printk(KERN_CONT "DTV7 ");
+        if (type & DTV78)
+               printk(KERN_CONT "DTV78 ");
+        if (type & DTV8)
+               printk(KERN_CONT "DTV8 ");
+        if (type & FM)
+               printk(KERN_CONT "FM ");
+        if (type & INPUT1)
+               printk(KERN_CONT "INPUT1 ");
+        if (type & LCD)
+               printk(KERN_CONT "LCD ");
+        if (type & NOGD)
+               printk(KERN_CONT "NOGD ");
+        if (type & MONO)
+               printk(KERN_CONT "MONO ");
+        if (type & ATSC)
+               printk(KERN_CONT "ATSC ");
+        if (type & IF)
+               printk(KERN_CONT "IF ");
+        if (type & LG60)
+               printk(KERN_CONT "LG60 ");
+        if (type & ATI638)
+               printk(KERN_CONT "ATI638 ");
+        if (type & OREN538)
+               printk(KERN_CONT "OREN538 ");
+        if (type & OREN36)
+               printk(KERN_CONT "OREN36 ");
+        if (type & TOYOTA388)
+               printk(KERN_CONT "TOYOTA388 ");
+        if (type & TOYOTA794)
+               printk(KERN_CONT "TOYOTA794 ");
+        if (type & DIBCOM52)
+               printk(KERN_CONT "DIBCOM52 ");
+        if (type & ZARLINK456)
+               printk(KERN_CONT "ZARLINK456 ");
+        if (type & CHINA)
+               printk(KERN_CONT "CHINA ");
+        if (type & F6MHZ)
+               printk(KERN_CONT "F6MHZ ");
+        if (type & INPUT2)
+               printk(KERN_CONT "INPUT2 ");
+        if (type & SCODE)
+               printk(KERN_CONT "SCODE ");
+        if (type & HAS_IF)
+               printk(KERN_CONT "HAS_IF_%d ", int_freq);
+}
+
+static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
+                        v4l2_std_id *id)
+{
+       struct xc4000_priv *priv = fe->tuner_priv;
+       int             i, best_i = -1;
+       unsigned int    best_nr_diffs = 255U;
+
+       if (!priv->firm) {
+               printk(KERN_ERR "Error! firmware not loaded\n");
+               return -EINVAL;
+       }
+
+       if (((type & ~SCODE) == 0) && (*id == 0))
+               *id = V4L2_STD_PAL;
+
+       /* Seek for generic video standard match */
+       for (i = 0; i < priv->firm_size; i++) {
+               v4l2_std_id     id_diff_mask =
+                       (priv->firm[i].id ^ (*id)) & (*id);
+               unsigned int    type_diff_mask =
+                       (priv->firm[i].type ^ type)
+                       & (BASE_TYPES | DTV_TYPES | LCD | NOGD | MONO | SCODE);
+               unsigned int    nr_diffs;
+
+               if (type_diff_mask
+                   & (BASE | INIT1 | FM | DTV6 | DTV7 | DTV78 | DTV8 | SCODE))
+                       continue;
+
+               nr_diffs = hweight64(id_diff_mask) + hweight32(type_diff_mask);
+               if (!nr_diffs)  /* Supports all the requested standards */
+                       goto found;
+
+               if (nr_diffs < best_nr_diffs) {
+                       best_nr_diffs = nr_diffs;
+                       best_i = i;
+               }
+       }
+
+       /* FIXME: Would make sense to seek for type "hint" match ? */
+       if (best_i < 0) {
+               i = -ENOENT;
+               goto ret;
+       }
+
+       if (best_nr_diffs > 0U) {
+               printk(KERN_WARNING
+                      "Selecting best matching firmware (%u bits differ) for "
+                      "type=(%x), id %016llx:\n",
+                      best_nr_diffs, type, (unsigned long long)*id);
+               i = best_i;
+       }
+
+found:
+       *id = priv->firm[i].id;
+
+ret:
+       if (debug) {
+               printk(KERN_DEBUG "%s firmware for type=",
+                      (i < 0) ? "Can't find" : "Found");
+               dump_firm_type(type);
+               printk(KERN_DEBUG "(%x), id %016llx.\n", type, (unsigned long long)*id);
+       }
+       return i;
+}
+
+static int load_firmware(struct dvb_frontend *fe, unsigned int type,
+                        v4l2_std_id *id)
+{
+       struct xc4000_priv *priv = fe->tuner_priv;
+       int                pos, rc;
+       unsigned char      *p;
+
+       pos = seek_firmware(fe, type, id);
+       if (pos < 0)
+               return pos;
+
+       p = priv->firm[pos].ptr;
+
+       /* Don't complain when the request fails because of i2c stretching */
+       priv->ignore_i2c_write_errors = 1;
+
+       rc = xc_load_i2c_sequence(fe, p);
+
+       priv->ignore_i2c_write_errors = 0;
+
+       return rc;
+}
+
+static int xc4000_fwupload(struct dvb_frontend *fe)
+{
+       struct xc4000_priv *priv = fe->tuner_priv;
+       const struct firmware *fw   = NULL;
+       const unsigned char   *p, *endp;
+       int                   rc = 0;
+       int                   n, n_array;
+       char                  name[33];
+       const char            *fname;
+
+       if (firmware_name[0] != '\0')
+               fname = firmware_name;
+       else
+               fname = XC4000_DEFAULT_FIRMWARE;
+
+       dprintk(1, "Reading firmware %s\n", fname);
+       rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent);
+       if (rc < 0) {
+               if (rc == -ENOENT)
+                       printk(KERN_ERR "Error: firmware %s not found.\n", fname);
+               else
+                       printk(KERN_ERR "Error %d while requesting firmware %s\n",
+                              rc, fname);
+
+               return rc;
+       }
+       p = fw->data;
+       endp = p + fw->size;
+
+       if (fw->size < sizeof(name) - 1 + 2 + 2) {
+               printk(KERN_ERR "Error: firmware file %s has invalid size!\n",
+                      fname);
+               goto corrupt;
+       }
+
+       memcpy(name, p, sizeof(name) - 1);
+       name[sizeof(name) - 1] = '\0';
+       p += sizeof(name) - 1;
+
+       priv->firm_version = get_unaligned_le16(p);
+       p += 2;
+
+       n_array = get_unaligned_le16(p);
+       p += 2;
+
+       dprintk(1, "Loading %d firmware images from %s, type: %s, ver %d.%d\n",
+               n_array, fname, name,
+               priv->firm_version >> 8, priv->firm_version & 0xff);
+
+       priv->firm = kcalloc(n_array, sizeof(*priv->firm), GFP_KERNEL);
+       if (priv->firm == NULL) {
+               printk(KERN_ERR "Not enough memory to load firmware file.\n");
+               rc = -ENOMEM;
+               goto done;
+       }
+       priv->firm_size = n_array;
+
+       n = -1;
+       while (p < endp) {
+               __u32 type, size;
+               v4l2_std_id id;
+               __u16 int_freq = 0;
+
+               n++;
+               if (n >= n_array) {
+                       printk(KERN_ERR "More firmware images in file than "
+                              "were expected!\n");
+                       goto corrupt;
+               }
+
+               /* Checks if there's enough bytes to read */
+               if (endp - p < sizeof(type) + sizeof(id) + sizeof(size))
+                       goto header;
+
+               type = get_unaligned_le32(p);
+               p += sizeof(type);
+
+               id = get_unaligned_le64(p);
+               p += sizeof(id);
+
+               if (type & HAS_IF) {
+                       int_freq = get_unaligned_le16(p);
+                       p += sizeof(int_freq);
+                       if (endp - p < sizeof(size))
+                               goto header;
+               }
+
+               size = get_unaligned_le32(p);
+               p += sizeof(size);
+
+               if (!size || size > endp - p) {
+                       printk(KERN_ERR "Firmware type (%x), id %llx is corrupted (size=%d, expected %d)\n",
+                              type, (unsigned long long)id,
+                              (unsigned)(endp - p), size);
+                       goto corrupt;
+               }
+
+               priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
+               if (priv->firm[n].ptr == NULL) {
+                       printk(KERN_ERR "Not enough memory to load firmware file.\n");
+                       rc = -ENOMEM;
+                       goto done;
+               }
+
+               if (debug) {
+                       printk(KERN_DEBUG "Reading firmware type ");
+                       dump_firm_type_and_int_freq(type, int_freq);
+                       printk(KERN_DEBUG "(%x), id %llx, size=%d.\n",
+                              type, (unsigned long long)id, size);
+               }
+
+               memcpy(priv->firm[n].ptr, p, size);
+               priv->firm[n].type = type;
+               priv->firm[n].id   = id;
+               priv->firm[n].size = size;
+               priv->firm[n].int_freq = int_freq;
+
+               p += size;
+       }
+
+       if (n + 1 != priv->firm_size) {
+               printk(KERN_ERR "Firmware file is incomplete!\n");
+               goto corrupt;
+       }
+
+       goto done;
+
+header:
+       printk(KERN_ERR "Firmware header is incomplete!\n");
+corrupt:
+       rc = -EINVAL;
+       printk(KERN_ERR "Error: firmware file is corrupted!\n");
+
+done:
+       release_firmware(fw);
+       if (rc == 0)
+               dprintk(1, "Firmware files loaded.\n");
+
+       return rc;
+}
+
+static int load_scode(struct dvb_frontend *fe, unsigned int type,
+                        v4l2_std_id *id, __u16 int_freq, int scode)
+{
+       struct xc4000_priv *priv = fe->tuner_priv;
+       int             pos, rc;
+       unsigned char   *p;
+       u8              scode_buf[13];
+       u8              indirect_mode[5];
+
+       dprintk(1, "%s called int_freq=%d\n", __func__, int_freq);
+
+       if (!int_freq) {
+               pos = seek_firmware(fe, type, id);
+               if (pos < 0)
+                       return pos;
+       } else {
+               for (pos = 0; pos < priv->firm_size; pos++) {
+                       if ((priv->firm[pos].int_freq == int_freq) &&
+                           (priv->firm[pos].type & HAS_IF))
+                               break;
+               }
+               if (pos == priv->firm_size)
+                       return -ENOENT;
+       }
+
+       p = priv->firm[pos].ptr;
+
+       if (priv->firm[pos].size != 12 * 16 || scode >= 16)
+               return -EINVAL;
+       p += 12 * scode;
+
+       if (debug) {
+               tuner_info("Loading SCODE for type=");
+               dump_firm_type_and_int_freq(priv->firm[pos].type,
+                                           priv->firm[pos].int_freq);
+               printk(KERN_CONT "(%x), id %016llx.\n", priv->firm[pos].type,
+                      (unsigned long long)*id);
+       }
+
+       scode_buf[0] = 0x00;
+       memcpy(&scode_buf[1], p, 12);
+
+       /* Enter direct-mode */
+       rc = xc_write_reg(priv, XREG_DIRECTSITTING_MODE, 0);
+       if (rc < 0) {
+               printk(KERN_ERR "failed to put device into direct mode!\n");
+               return -EIO;
+       }
+
+       rc = xc_send_i2c_data(priv, scode_buf, 13);
+       if (rc != 0) {
+               /* Even if the send failed, make sure we set back to indirect
+                  mode */
+               printk(KERN_ERR "Failed to set scode %d\n", rc);
+       }
+
+       /* Switch back to indirect-mode */
+       memset(indirect_mode, 0, sizeof(indirect_mode));
+       indirect_mode[4] = 0x88;
+       xc_send_i2c_data(priv, indirect_mode, sizeof(indirect_mode));
+       msleep(10);
+
+       return 0;
+}
+
+static int check_firmware(struct dvb_frontend *fe, unsigned int type,
+                         v4l2_std_id std, __u16 int_freq)
+{
+       struct xc4000_priv         *priv = fe->tuner_priv;
+       struct firmware_properties new_fw;
+       int                        rc = 0, is_retry = 0;
+       u16                        hwmodel;
+       v4l2_std_id                std0;
+       u8                         hw_major, hw_minor, fw_major, fw_minor;
+
+       dprintk(1, "%s called\n", __func__);
+
+       if (!priv->firm) {
+               rc = xc4000_fwupload(fe);
+               if (rc < 0)
+                       return rc;
+       }
+
+retry:
+       new_fw.type = type;
+       new_fw.id = std;
+       new_fw.std_req = std;
+       new_fw.scode_table = SCODE;
+       new_fw.scode_nr = 0;
+       new_fw.int_freq = int_freq;
+
+       dprintk(1, "checking firmware, user requested type=");
+       if (debug) {
+               dump_firm_type(new_fw.type);
+               printk(KERN_CONT "(%x), id %016llx, ", new_fw.type,
+                      (unsigned long long)new_fw.std_req);
+               if (!int_freq)
+                       printk(KERN_CONT "scode_tbl ");
+               else
+                       printk(KERN_CONT "int_freq %d, ", new_fw.int_freq);
+               printk(KERN_CONT "scode_nr %d\n", new_fw.scode_nr);
+       }
+
+       /* No need to reload base firmware if it matches */
+       if (priv->cur_fw.type & BASE) {
+               dprintk(1, "BASE firmware not changed.\n");
+               goto skip_base;
+       }
+
+       /* Updating BASE - forget about all currently loaded firmware */
+       memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
+
+       /* Reset is needed before loading firmware */
+       rc = xc4000_tuner_reset(fe);
+       if (rc < 0)
+               goto fail;
+
+       /* BASE firmwares are all std0 */
+       std0 = 0;
+       rc = load_firmware(fe, BASE, &std0);
+       if (rc < 0) {
+               printk(KERN_ERR "Error %d while loading base firmware\n", rc);
+               goto fail;
+       }
+
+       /* Load INIT1, if needed */
+       dprintk(1, "Load init1 firmware, if exists\n");
+
+       rc = load_firmware(fe, BASE | INIT1, &std0);
+       if (rc == -ENOENT)
+               rc = load_firmware(fe, BASE | INIT1, &std0);
+       if (rc < 0 && rc != -ENOENT) {
+               tuner_err("Error %d while loading init1 firmware\n",
+                         rc);
+               goto fail;
+       }
+
+skip_base:
+       /*
+        * No need to reload standard specific firmware if base firmware
+        * was not reloaded and requested video standards have not changed.
+        */
+       if (priv->cur_fw.type == (BASE | new_fw.type) &&
+           priv->cur_fw.std_req == std) {
+               dprintk(1, "Std-specific firmware already loaded.\n");
+               goto skip_std_specific;
+       }
+
+       /* Reloading std-specific firmware forces a SCODE update */
+       priv->cur_fw.scode_table = 0;
+
+       /* Load the standard firmware */
+       rc = load_firmware(fe, new_fw.type, &new_fw.id);
+
+       if (rc < 0)
+               goto fail;
+
+skip_std_specific:
+       if (priv->cur_fw.scode_table == new_fw.scode_table &&
+           priv->cur_fw.scode_nr == new_fw.scode_nr) {
+               dprintk(1, "SCODE firmware already loaded.\n");
+               goto check_device;
+       }
+
+       /* Load SCODE firmware, if exists */
+       rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id,
+                       new_fw.int_freq, new_fw.scode_nr);
+       if (rc != 0)
+               dprintk(1, "load scode failed %d\n", rc);
+
+check_device:
+       rc = xc4000_readreg(priv, XREG_PRODUCT_ID, &hwmodel);
+
+       if (xc_get_version(priv, &hw_major, &hw_minor, &fw_major,
+                          &fw_minor) != 0) {
+               printk(KERN_ERR "Unable to read tuner registers.\n");
+               goto fail;
+       }
+
+       dprintk(1, "Device is Xceive %d version %d.%d, "
+               "firmware version %d.%d\n",
+               hwmodel, hw_major, hw_minor, fw_major, fw_minor);
+
+       /* Check firmware version against what we downloaded. */
+       if (priv->firm_version != ((fw_major << 8) | fw_minor)) {
+               printk(KERN_WARNING
+                      "Incorrect readback of firmware version %d.%d.\n",
+                      fw_major, fw_minor);
+               goto fail;
+       }
+
+       /* Check that the tuner hardware model remains consistent over time. */
+       if (priv->hwmodel == 0 &&
+           (hwmodel == XC_PRODUCT_ID_XC4000 ||
+            hwmodel == XC_PRODUCT_ID_XC4100)) {
+               priv->hwmodel = hwmodel;
+               priv->hwvers = (hw_major << 8) | hw_minor;
+       } else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel ||
+                  priv->hwvers != ((hw_major << 8) | hw_minor)) {
+               printk(KERN_WARNING
+                      "Read invalid device hardware information - tuner "
+                      "hung?\n");
+               goto fail;
+       }
+
+       memcpy(&priv->cur_fw, &new_fw, sizeof(priv->cur_fw));
+
+       /*
+        * By setting BASE in cur_fw.type only after successfully loading all
+        * firmwares, we can:
+        * 1. Identify that BASE firmware with type=0 has been loaded;
+        * 2. Tell whether BASE firmware was just changed the next time through.
+        */
+       priv->cur_fw.type |= BASE;
+
+       return 0;
+
+fail:
+       memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
+       if (!is_retry) {
+               msleep(50);
+               is_retry = 1;
+               dprintk(1, "Retrying firmware load\n");
+               goto retry;
+       }
+
+       if (rc == -ENOENT)
+               rc = -EINVAL;
+       return rc;
+}
+
+static void xc_debug_dump(struct xc4000_priv *priv)
+{
+       u16     adc_envelope;
+       u32     freq_error_hz = 0;
+       u16     lock_status;
+       u32     hsync_freq_hz = 0;
+       u16     frame_lines;
+       u16     quality;
+       u16     signal = 0;
+       u16     noise = 0;
+       u8      hw_majorversion = 0, hw_minorversion = 0;
+       u8      fw_majorversion = 0, fw_minorversion = 0;
+
+       xc_get_adc_envelope(priv, &adc_envelope);
+       dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
+
+       xc_get_frequency_error(priv, &freq_error_hz);
+       dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
+
+       xc_get_lock_status(priv, &lock_status);
+       dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
+               lock_status);
+
+       xc_get_version(priv, &hw_majorversion, &hw_minorversion,
+                      &fw_majorversion, &fw_minorversion);
+       dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n",
+               hw_majorversion, hw_minorversion,
+               fw_majorversion, fw_minorversion);
+
+       if (priv->video_standard < XC4000_DTV6) {
+               xc_get_hsync_freq(priv, &hsync_freq_hz);
+               dprintk(1, "*** Horizontal sync frequency = %d Hz\n",
+                       hsync_freq_hz);
+
+               xc_get_frame_lines(priv, &frame_lines);
+               dprintk(1, "*** Frame lines = %d\n", frame_lines);
+       }
+
+       xc_get_quality(priv, &quality);
+       dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
+
+       xc_get_signal_level(priv, &signal);
+       dprintk(1, "*** Signal level = -%ddB (%d)\n", signal >> 8, signal);
+
+       xc_get_noise_level(priv, &noise);
+       dprintk(1, "*** Noise level = %ddB (%d)\n", noise >> 8, noise);
+}
+
+static int xc4000_set_params(struct dvb_frontend *fe)
+{
+       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+       u32 delsys = c->delivery_system;
+       u32 bw = c->bandwidth_hz;
+       struct xc4000_priv *priv = fe->tuner_priv;
+       unsigned int type;
+       int     ret = -EREMOTEIO;
+
+       dprintk(1, "%s() frequency=%d (Hz)\n", __func__, c->frequency);
+
+       mutex_lock(&priv->lock);
+
+       switch (delsys) {
+       case SYS_ATSC:
+               dprintk(1, "%s() VSB modulation\n", __func__);
+               priv->rf_mode = XC_RF_MODE_AIR;
+               priv->freq_hz = c->frequency - 1750000;
+               priv->video_standard = XC4000_DTV6;
+               type = DTV6;
+               break;
+       case SYS_DVBC_ANNEX_B:
+               dprintk(1, "%s() QAM modulation\n", __func__);
+               priv->rf_mode = XC_RF_MODE_CABLE;
+               priv->freq_hz = c->frequency - 1750000;
+               priv->video_standard = XC4000_DTV6;
+               type = DTV6;
+               break;
+       case SYS_DVBT:
+       case SYS_DVBT2:
+               dprintk(1, "%s() OFDM\n", __func__);
+               if (bw == 0) {
+                       if (c->frequency < 400000000) {
+                               priv->freq_hz = c->frequency - 2250000;
+                       } else {
+                               priv->freq_hz = c->frequency - 2750000;
+                       }
+                       priv->video_standard = XC4000_DTV7_8;
+                       type = DTV78;
+               } else if (bw <= 6000000) {
+                       priv->video_standard = XC4000_DTV6;
+                       priv->freq_hz = c->frequency - 1750000;
+                       type = DTV6;
+               } else if (bw <= 7000000) {
+                       priv->video_standard = XC4000_DTV7;
+                       priv->freq_hz = c->frequency - 2250000;
+                       type = DTV7;
+               } else {
+                       priv->video_standard = XC4000_DTV8;
+                       priv->freq_hz = c->frequency - 2750000;
+                       type = DTV8;
+               }
+               priv->rf_mode = XC_RF_MODE_AIR;
+               break;
+       default:
+               printk(KERN_ERR "xc4000 delivery system not supported!\n");
+               ret = -EINVAL;
+               goto fail;
+       }
+
+       dprintk(1, "%s() frequency=%d (compensated)\n",
+               __func__, priv->freq_hz);
+
+       /* Make sure the correct firmware type is loaded */
+       if (check_firmware(fe, type, 0, priv->if_khz) != 0)
+               goto fail;
+
+       priv->bandwidth = c->bandwidth_hz;
+
+       ret = xc_set_signal_source(priv, priv->rf_mode);
+       if (ret != 0) {
+               printk(KERN_ERR "xc4000: xc_set_signal_source(%d) failed\n",
+                      priv->rf_mode);
+               goto fail;
+       } else {
+               u16     video_mode, audio_mode;
+               video_mode = xc4000_standard[priv->video_standard].video_mode;
+               audio_mode = xc4000_standard[priv->video_standard].audio_mode;
+               if (type == DTV6 && priv->firm_version != 0x0102)
+                       video_mode |= 0x0001;
+               ret = xc_set_tv_standard(priv, video_mode, audio_mode);
+               if (ret != 0) {
+                       printk(KERN_ERR "xc4000: xc_set_tv_standard failed\n");
+                       /* DJH - do not return when it fails... */
+                       /* goto fail; */
+               }
+       }
+
+       if (xc_write_reg(priv, XREG_D_CODE, 0) == 0)
+               ret = 0;
+       if (priv->dvb_amplitude != 0) {
+               if (xc_write_reg(priv, XREG_AMPLITUDE,
+                                (priv->firm_version != 0x0102 ||
+                                 priv->dvb_amplitude != 134 ?
+                                 priv->dvb_amplitude : 132)) != 0)
+                       ret = -EREMOTEIO;
+       }
+       if (priv->set_smoothedcvbs != 0) {
+               if (xc_write_reg(priv, XREG_SMOOTHEDCVBS, 1) != 0)
+                       ret = -EREMOTEIO;
+       }
+       if (ret != 0) {
+               printk(KERN_ERR "xc4000: setting registers failed\n");
+               /* goto fail; */
+       }
+
+       xc_tune_channel(priv, priv->freq_hz);
+
+       ret = 0;
+
+fail:
+       mutex_unlock(&priv->lock);
+
+       return ret;
+}
+
+static int xc4000_set_analog_params(struct dvb_frontend *fe,
+       struct analog_parameters *params)
+{
+       struct xc4000_priv *priv = fe->tuner_priv;
+       unsigned int type = 0;
+       int     ret = -EREMOTEIO;
+
+       if (params->mode == V4L2_TUNER_RADIO) {
+               dprintk(1, "%s() frequency=%d (in units of 62.5Hz)\n",
+                       __func__, params->frequency);
+
+               mutex_lock(&priv->lock);
+
+               params->std = 0;
+               priv->freq_hz = params->frequency * 125L / 2;
+
+               if (audio_std & XC4000_AUDIO_STD_INPUT1) {
+                       priv->video_standard = XC4000_FM_Radio_INPUT1;
+                       type = FM | INPUT1;
+               } else {
+                       priv->video_standard = XC4000_FM_Radio_INPUT2;
+                       type = FM | INPUT2;
+               }
+
+               goto tune_channel;
+       }
+
+       dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
+               __func__, params->frequency);
+
+       mutex_lock(&priv->lock);
+
+       /* params->frequency is in units of 62.5khz */
+       priv->freq_hz = params->frequency * 62500;
+
+       params->std &= V4L2_STD_ALL;
+       /* if std is not defined, choose one */
+       if (!params->std)
+               params->std = V4L2_STD_PAL_BG;
+
+       if (audio_std & XC4000_AUDIO_STD_MONO)
+               type = MONO;
+
+       if (params->std & V4L2_STD_MN) {
+               params->std = V4L2_STD_MN;
+               if (audio_std & XC4000_AUDIO_STD_MONO) {
+                       priv->video_standard = XC4000_MN_NTSC_PAL_Mono;
+               } else if (audio_std & XC4000_AUDIO_STD_A2) {
+                       params->std |= V4L2_STD_A2;
+                       priv->video_standard = XC4000_MN_NTSC_PAL_A2;
+               } else {
+                       params->std |= V4L2_STD_BTSC;
+                       priv->video_standard = XC4000_MN_NTSC_PAL_BTSC;
+               }
+               goto tune_channel;
+       }
+
+       if (params->std & V4L2_STD_PAL_BG) {
+               params->std = V4L2_STD_PAL_BG;
+               if (audio_std & XC4000_AUDIO_STD_MONO) {
+                       priv->video_standard = XC4000_BG_PAL_MONO;
+               } else if (!(audio_std & XC4000_AUDIO_STD_A2)) {
+                       if (!(audio_std & XC4000_AUDIO_STD_B)) {
+                               params->std |= V4L2_STD_NICAM_A;
+                               priv->video_standard = XC4000_BG_PAL_NICAM;
+                       } else {
+                               params->std |= V4L2_STD_NICAM_B;
+                               priv->video_standard = XC4000_BG_PAL_NICAM;
+                       }
+               } else {
+                       if (!(audio_std & XC4000_AUDIO_STD_B)) {
+                               params->std |= V4L2_STD_A2_A;
+                               priv->video_standard = XC4000_BG_PAL_A2;
+                       } else {
+                               params->std |= V4L2_STD_A2_B;
+                               priv->video_standard = XC4000_BG_PAL_A2;
+                       }
+               }
+               goto tune_channel;
+       }
+
+       if (params->std & V4L2_STD_PAL_I) {
+               /* default to NICAM audio standard */
+               params->std = V4L2_STD_PAL_I | V4L2_STD_NICAM;
+               if (audio_std & XC4000_AUDIO_STD_MONO)
+                       priv->video_standard = XC4000_I_PAL_NICAM_MONO;
+               else
+                       priv->video_standard = XC4000_I_PAL_NICAM;
+               goto tune_channel;
+       }
+
+       if (params->std & V4L2_STD_PAL_DK) {
+               params->std = V4L2_STD_PAL_DK;
+               if (audio_std & XC4000_AUDIO_STD_MONO) {
+                       priv->video_standard = XC4000_DK_PAL_MONO;
+               } else if (audio_std & XC4000_AUDIO_STD_A2) {
+                       params->std |= V4L2_STD_A2;
+                       priv->video_standard = XC4000_DK_PAL_A2;
+               } else {
+                       params->std |= V4L2_STD_NICAM;
+                       priv->video_standard = XC4000_DK_PAL_NICAM;
+               }
+               goto tune_channel;
+       }
+
+       if (params->std & V4L2_STD_SECAM_DK) {
+               /* default to A2 audio standard */
+               params->std = V4L2_STD_SECAM_DK | V4L2_STD_A2;
+               if (audio_std & XC4000_AUDIO_STD_L) {
+                       type = 0;
+                       priv->video_standard = XC4000_DK_SECAM_NICAM;
+               } else if (audio_std & XC4000_AUDIO_STD_MONO) {
+                       priv->video_standard = XC4000_DK_SECAM_A2MONO;
+               } else if (audio_std & XC4000_AUDIO_STD_K3) {
+                       params->std |= V4L2_STD_SECAM_K3;
+                       priv->video_standard = XC4000_DK_SECAM_A2LDK3;
+               } else {
+                       priv->video_standard = XC4000_DK_SECAM_A2DK1;
+               }
+               goto tune_channel;
+       }
+
+       if (params->std & V4L2_STD_SECAM_L) {
+               /* default to NICAM audio standard */
+               type = 0;
+               params->std = V4L2_STD_SECAM_L | V4L2_STD_NICAM;
+               priv->video_standard = XC4000_L_SECAM_NICAM;
+               goto tune_channel;
+       }
+
+       if (params->std & V4L2_STD_SECAM_LC) {
+               /* default to NICAM audio standard */
+               type = 0;
+               params->std = V4L2_STD_SECAM_LC | V4L2_STD_NICAM;
+               priv->video_standard = XC4000_LC_SECAM_NICAM;
+               goto tune_channel;
+       }
+
+tune_channel:
+       /* FIXME: it could be air. */
+       priv->rf_mode = XC_RF_MODE_CABLE;
+
+       if (check_firmware(fe, type, params->std,
+                          xc4000_standard[priv->video_standard].int_freq) != 0)
+               goto fail;
+
+       ret = xc_set_signal_source(priv, priv->rf_mode);
+       if (ret != 0) {
+               printk(KERN_ERR
+                      "xc4000: xc_set_signal_source(%d) failed\n",
+                      priv->rf_mode);
+               goto fail;
+       } else {
+               u16     video_mode, audio_mode;
+               video_mode = xc4000_standard[priv->video_standard].video_mode;
+               audio_mode = xc4000_standard[priv->video_standard].audio_mode;
+               if (priv->video_standard < XC4000_BG_PAL_A2) {
+                       if (type & NOGD)
+                               video_mode &= 0xFF7F;
+               } else if (priv->video_standard < XC4000_I_PAL_NICAM) {
+                       if (priv->firm_version == 0x0102)
+                               video_mode &= 0xFEFF;
+                       if (audio_std & XC4000_AUDIO_STD_B)
+                               video_mode |= 0x0080;
+               }
+               ret = xc_set_tv_standard(priv, video_mode, audio_mode);
+               if (ret != 0) {
+                       printk(KERN_ERR "xc4000: xc_set_tv_standard failed\n");
+                       goto fail;
+               }
+       }
+
+       if (xc_write_reg(priv, XREG_D_CODE, 0) == 0)
+               ret = 0;
+       if (xc_write_reg(priv, XREG_AMPLITUDE, 1) != 0)
+               ret = -EREMOTEIO;
+       if (priv->set_smoothedcvbs != 0) {
+               if (xc_write_reg(priv, XREG_SMOOTHEDCVBS, 1) != 0)
+                       ret = -EREMOTEIO;
+       }
+       if (ret != 0) {
+               printk(KERN_ERR "xc4000: setting registers failed\n");
+               goto fail;
+       }
+
+       xc_tune_channel(priv, priv->freq_hz);
+
+       ret = 0;
+
+fail:
+       mutex_unlock(&priv->lock);
+
+       return ret;
+}
+
+static int xc4000_get_signal(struct dvb_frontend *fe, u16 *strength)
+{
+       struct xc4000_priv *priv = fe->tuner_priv;
+       u16 value = 0;
+       int rc;
+
+       mutex_lock(&priv->lock);
+       rc = xc4000_readreg(priv, XREG_SIGNAL_LEVEL, &value);
+       mutex_unlock(&priv->lock);
+
+       if (rc < 0)
+               goto ret;
+
+       /* Informations from real testing of DVB-T and radio part,
+          coeficient for one dB is 0xff.
+        */
+       tuner_dbg("Signal strength: -%ddB (%05d)\n", value >> 8, value);
+
+       /* all known digital modes */
+       if ((priv->video_standard == XC4000_DTV6) ||
+           (priv->video_standard == XC4000_DTV7) ||
+           (priv->video_standard == XC4000_DTV7_8) ||
+           (priv->video_standard == XC4000_DTV8))
+               goto digital;
+
+       /* Analog mode has NOISE LEVEL important, signal
+          depends only on gain of antenna and amplifiers,
+          but it doesn't tell anything about real quality
+          of reception.
+        */
+       mutex_lock(&priv->lock);
+       rc = xc4000_readreg(priv, XREG_NOISE_LEVEL, &value);
+       mutex_unlock(&priv->lock);
+
+       tuner_dbg("Noise level: %ddB (%05d)\n", value >> 8, value);
+
+       /* highest noise level: 32dB */
+       if (value >= 0x2000) {
+               value = 0;
+       } else {
+               value = ~value << 3;
+       }
+
+       goto ret;
+
+       /* Digital mode has SIGNAL LEVEL important and real
+          noise level is stored in demodulator registers.
+        */
+digital:
+       /* best signal: -50dB */
+       if (value <= 0x3200) {
+               value = 0xffff;
+       /* minimum: -114dB - should be 0x7200 but real zero is 0x713A */
+       } else if (value >= 0x713A) {
+               value = 0;
+       } else {
+               value = ~(value - 0x3200) << 2;
+       }
+
+ret:
+       *strength = value;
+
+       return rc;
+}
+
+static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
+{
+       struct xc4000_priv *priv = fe->tuner_priv;
+
+       *freq = priv->freq_hz;
+
+       if (debug) {
+               mutex_lock(&priv->lock);
+               if ((priv->cur_fw.type
+                    & (BASE | FM | DTV6 | DTV7 | DTV78 | DTV8)) == BASE) {
+                       u16     snr = 0;
+                       if (xc4000_readreg(priv, XREG_SNR, &snr) == 0) {
+                               mutex_unlock(&priv->lock);
+                               dprintk(1, "%s() freq = %u, SNR = %d\n",
+                                       __func__, *freq, snr);
+                               return 0;
+                       }
+               }
+               mutex_unlock(&priv->lock);
+       }
+
+       dprintk(1, "%s()\n", __func__);
+
+       return 0;
+}
+
+static int xc4000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
+{
+       struct xc4000_priv *priv = fe->tuner_priv;
+       dprintk(1, "%s()\n", __func__);
+
+       *bw = priv->bandwidth;
+       return 0;
+}
+
+static int xc4000_get_status(struct dvb_frontend *fe, u32 *status)
+{
+       struct xc4000_priv *priv = fe->tuner_priv;
+       u16     lock_status = 0;
+
+       mutex_lock(&priv->lock);
+
+       if (priv->cur_fw.type & BASE)
+               xc_get_lock_status(priv, &lock_status);
+
+       *status = (lock_status == 1 ?
+                  TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO : 0);
+       if (priv->cur_fw.type & (DTV6 | DTV7 | DTV78 | DTV8))
+               *status &= (~TUNER_STATUS_STEREO);
+
+       mutex_unlock(&priv->lock);
+
+       dprintk(2, "%s() lock_status = %d\n", __func__, lock_status);
+
+       return 0;
+}
+
+static int xc4000_sleep(struct dvb_frontend *fe)
+{
+       struct xc4000_priv *priv = fe->tuner_priv;
+       int     ret = 0;
+
+       dprintk(1, "%s()\n", __func__);
+
+       mutex_lock(&priv->lock);
+
+       /* Avoid firmware reload on slow devices */
+       if ((no_poweroff == 2 ||
+            (no_poweroff == 0 && priv->default_pm != 0)) &&
+           (priv->cur_fw.type & BASE) != 0) {
+               /* force reset and firmware reload */
+               priv->cur_fw.type = XC_POWERED_DOWN;
+
+               if (xc_write_reg(priv, XREG_POWER_DOWN, 0) != 0) {
+                       printk(KERN_ERR
+                              "xc4000: %s() unable to shutdown tuner\n",
+                              __func__);
+                       ret = -EREMOTEIO;
+               }
+               msleep(20);
+       }
+
+       mutex_unlock(&priv->lock);
+
+       return ret;
+}
+
+static int xc4000_init(struct dvb_frontend *fe)
+{
+       dprintk(1, "%s()\n", __func__);
+
+       return 0;
+}
+
+static int xc4000_release(struct dvb_frontend *fe)
+{
+       struct xc4000_priv *priv = fe->tuner_priv;
+
+       dprintk(1, "%s()\n", __func__);
+
+       mutex_lock(&xc4000_list_mutex);
+
+       if (priv)
+               hybrid_tuner_release_state(priv);
+
+       mutex_unlock(&xc4000_list_mutex);
+
+       fe->tuner_priv = NULL;
+
+       return 0;
+}
+
+static const struct dvb_tuner_ops xc4000_tuner_ops = {
+       .info = {
+               .name           = "Xceive XC4000",
+               .frequency_min  =    1000000,
+               .frequency_max  = 1023000000,
+               .frequency_step =      50000,
+       },
+
+       .release           = xc4000_release,
+       .init              = xc4000_init,
+       .sleep             = xc4000_sleep,
+
+       .set_params        = xc4000_set_params,
+       .set_analog_params = xc4000_set_analog_params,
+       .get_frequency     = xc4000_get_frequency,
+       .get_rf_strength   = xc4000_get_signal,
+       .get_bandwidth     = xc4000_get_bandwidth,
+       .get_status        = xc4000_get_status
+};
+
+struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
+                                  struct i2c_adapter *i2c,
+                                  struct xc4000_config *cfg)
+{
+       struct xc4000_priv *priv = NULL;
+       int     instance;
+       u16     id = 0;
+
+       dprintk(1, "%s(%d-%04x)\n", __func__,
+               i2c ? i2c_adapter_id(i2c) : -1,
+               cfg ? cfg->i2c_address : -1);
+
+       mutex_lock(&xc4000_list_mutex);
+
+       instance = hybrid_tuner_request_state(struct xc4000_priv, priv,
+                                             hybrid_tuner_instance_list,
+                                             i2c, cfg->i2c_address, "xc4000");
+       switch (instance) {
+       case 0:
+               goto fail;
+               break;
+       case 1:
+               /* new tuner instance */
+               priv->bandwidth = 6000000;
+               /* set default configuration */
+               priv->if_khz = 4560;
+               priv->default_pm = 0;
+               priv->dvb_amplitude = 134;
+               priv->set_smoothedcvbs = 1;
+               mutex_init(&priv->lock);
+               fe->tuner_priv = priv;
+               break;
+       default:
+               /* existing tuner instance */
+               fe->tuner_priv = priv;
+               break;
+       }
+
+       if (cfg->if_khz != 0) {
+               /* copy configuration if provided by the caller */
+               priv->if_khz = cfg->if_khz;
+               priv->default_pm = cfg->default_pm;
+               priv->dvb_amplitude = cfg->dvb_amplitude;
+               priv->set_smoothedcvbs = cfg->set_smoothedcvbs;
+       }
+
+       /* Check if firmware has been loaded. It is possible that another
+          instance of the driver has loaded the firmware.
+        */
+
+       if (instance == 1) {
+               if (xc4000_readreg(priv, XREG_PRODUCT_ID, &id) != 0)
+                       goto fail;
+       } else {
+               id = ((priv->cur_fw.type & BASE) != 0 ?
+                     priv->hwmodel : XC_PRODUCT_ID_FW_NOT_LOADED);
+       }
+
+       switch (id) {
+       case XC_PRODUCT_ID_XC4000:
+       case XC_PRODUCT_ID_XC4100:
+               printk(KERN_INFO
+                       "xc4000: Successfully identified at address 0x%02x\n",
+                       cfg->i2c_address);
+               printk(KERN_INFO
+                       "xc4000: Firmware has been loaded previously\n");
+               break;
+       case XC_PRODUCT_ID_FW_NOT_LOADED:
+               printk(KERN_INFO
+                       "xc4000: Successfully identified at address 0x%02x\n",
+                       cfg->i2c_address);
+               printk(KERN_INFO
+                       "xc4000: Firmware has not been loaded previously\n");
+               break;
+       default:
+               printk(KERN_ERR
+                       "xc4000: Device not found at addr 0x%02x (0x%x)\n",
+                       cfg->i2c_address, id);
+               goto fail;
+       }
+
+       mutex_unlock(&xc4000_list_mutex);
+
+       memcpy(&fe->ops.tuner_ops, &xc4000_tuner_ops,
+               sizeof(struct dvb_tuner_ops));
+
+       if (instance == 1) {
+               int     ret;
+               mutex_lock(&priv->lock);
+               ret = xc4000_fwupload(fe);
+               mutex_unlock(&priv->lock);
+               if (ret != 0)
+                       goto fail2;
+       }
+
+       return fe;
+fail:
+       mutex_unlock(&xc4000_list_mutex);
+fail2:
+       xc4000_release(fe);
+       return NULL;
+}
+EXPORT_SYMBOL(xc4000_attach);
+
+MODULE_AUTHOR("Steven Toth, Davide Ferri");
+MODULE_DESCRIPTION("Xceive xc4000 silicon tuner driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/xc4000.h b/drivers/media/tuners/xc4000.h
new file mode 100644 (file)
index 0000000..e6a44d1
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *  Driver for Xceive XC4000 "QAM/8VSB single chip tuner"
+ *
+ *  Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
+ *
+ *  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 __XC4000_H__
+#define __XC4000_H__
+
+#include <linux/firmware.h>
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct xc4000_config {
+       u8      i2c_address;
+       /* if non-zero, power management is enabled by default */
+       u8      default_pm;
+       /* value to be written to XREG_AMPLITUDE in DVB-T mode (0: no write) */
+       u8      dvb_amplitude;
+       /* if non-zero, register 0x0E is set to filter analog TV video output */
+       u8      set_smoothedcvbs;
+       /* IF for DVB-T */
+       u32     if_khz;
+};
+
+/* xc4000 callback command */
+#define XC4000_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 xc4000 driver cares not for this value, other than ensuring
+ * it's passed back to a bridge during tuner_callback().
+ */
+
+#if defined(CONFIG_MEDIA_TUNER_XC4000) || (defined(CONFIG_MEDIA_TUNER_XC4000_MODULE) && defined(MODULE))
+extern struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
+                                         struct i2c_adapter *i2c,
+                                         struct xc4000_config *cfg);
+#else
+static inline struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
+                                                struct i2c_adapter *i2c,
+                                                struct xc4000_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c
new file mode 100644 (file)
index 0000000..dc93cf3
--- /dev/null
@@ -0,0 +1,1366 @@
+/*
+ *  Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
+ *
+ *  Copyright (c) 2007 Xceive Corporation
+ *  Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
+ *  Copyright (c) 2009 Devin Heitmueller <dheitmueller@kernellabs.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.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/videodev2.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+
+#include "xc5000.h"
+#include "tuner-i2c.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+static int no_poweroff;
+module_param(no_poweroff, int, 0644);
+MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n"
+       "\t\t1 keep device energized and with tuner ready all the times.\n"
+       "\t\tFaster, but consumes more power and keeps the device hotter");
+
+static DEFINE_MUTEX(xc5000_list_mutex);
+static LIST_HEAD(hybrid_tuner_instance_list);
+
+#define dprintk(level, fmt, arg...) if (debug >= level) \
+       printk(KERN_INFO "%s: " fmt, "xc5000", ## arg)
+
+struct xc5000_priv {
+       struct tuner_i2c_props i2c_props;
+       struct list_head hybrid_tuner_instance_list;
+
+       u32 if_khz;
+       u16 xtal_khz;
+       u32 freq_hz;
+       u32 bandwidth;
+       u8  video_standard;
+       u8  rf_mode;
+       u8  radio_input;
+
+       int chip_id;
+       u16 pll_register_no;
+       u8 init_status_supported;
+       u8 fw_checksum_supported;
+};
+
+/* Misc Defines */
+#define MAX_TV_STANDARD                        24
+#define XC_MAX_I2C_WRITE_LENGTH                64
+
+/* Signal Types */
+#define XC_RF_MODE_AIR                 0
+#define XC_RF_MODE_CABLE               1
+
+/* Result codes */
+#define XC_RESULT_SUCCESS              0
+#define XC_RESULT_RESET_FAILURE                1
+#define XC_RESULT_I2C_WRITE_FAILURE    2
+#define XC_RESULT_I2C_READ_FAILURE     3
+#define XC_RESULT_OUT_OF_RANGE         5
+
+/* Product id */
+#define XC_PRODUCT_ID_FW_NOT_LOADED    0x2000
+#define XC_PRODUCT_ID_FW_LOADED        0x1388
+
+/* Registers */
+#define XREG_INIT         0x00
+#define XREG_VIDEO_MODE   0x01
+#define XREG_AUDIO_MODE   0x02
+#define XREG_RF_FREQ      0x03
+#define XREG_D_CODE       0x04
+#define XREG_IF_OUT       0x05
+#define XREG_SEEK_MODE    0x07
+#define XREG_POWER_DOWN   0x0A /* Obsolete */
+/* Set the output amplitude - SIF for analog, DTVP/DTVN for digital */
+#define XREG_OUTPUT_AMP   0x0B
+#define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */
+#define XREG_SMOOTHEDCVBS 0x0E
+#define XREG_XTALFREQ     0x0F
+#define XREG_FINERFREQ    0x10
+#define XREG_DDIMODE      0x11
+
+#define XREG_ADC_ENV      0x00
+#define XREG_QUALITY      0x01
+#define XREG_FRAME_LINES  0x02
+#define XREG_HSYNC_FREQ   0x03
+#define XREG_LOCK         0x04
+#define XREG_FREQ_ERROR   0x05
+#define XREG_SNR          0x06
+#define XREG_VERSION      0x07
+#define XREG_PRODUCT_ID   0x08
+#define XREG_BUSY         0x09
+#define XREG_BUILD        0x0D
+#define XREG_TOTALGAIN    0x0F
+#define XREG_FW_CHECKSUM  0x12
+#define XREG_INIT_STATUS  0x13
+
+/*
+   Basic firmware description. This will remain with
+   the driver for documentation purposes.
+
+   This represents an I2C firmware file encoded as a
+   string of unsigned char. Format is as follows:
+
+   char[0  ]=len0_MSB  -> len = len_MSB * 256 + len_LSB
+   char[1  ]=len0_LSB  -> length of first write transaction
+   char[2  ]=data0 -> first byte to be sent
+   char[3  ]=data1
+   char[4  ]=data2
+   char[   ]=...
+   char[M  ]=dataN  -> last byte to be sent
+   char[M+1]=len1_MSB  -> len = len_MSB * 256 + len_LSB
+   char[M+2]=len1_LSB  -> length of second write transaction
+   char[M+3]=data0
+   char[M+4]=data1
+   ...
+   etc.
+
+   The [len] value should be interpreted as follows:
+
+   len= len_MSB _ len_LSB
+   len=1111_1111_1111_1111   : End of I2C_SEQUENCE
+   len=0000_0000_0000_0000   : Reset command: Do hardware reset
+   len=0NNN_NNNN_NNNN_NNNN   : Normal transaction: number of bytes = {1:32767)
+   len=1WWW_WWWW_WWWW_WWWW   : Wait command: wait for {1:32767} ms
+
+   For the RESET and WAIT commands, the two following bytes will contain
+   immediately the length of the following transaction.
+
+*/
+struct XC_TV_STANDARD {
+       char *Name;
+       u16 AudioMode;
+       u16 VideoMode;
+};
+
+/* Tuner standards */
+#define MN_NTSC_PAL_BTSC       0
+#define MN_NTSC_PAL_A2         1
+#define MN_NTSC_PAL_EIAJ       2
+#define MN_NTSC_PAL_Mono       3
+#define BG_PAL_A2              4
+#define BG_PAL_NICAM           5
+#define BG_PAL_MONO            6
+#define I_PAL_NICAM            7
+#define I_PAL_NICAM_MONO       8
+#define DK_PAL_A2              9
+#define DK_PAL_NICAM           10
+#define DK_PAL_MONO            11
+#define DK_SECAM_A2DK1         12
+#define DK_SECAM_A2LDK3        13
+#define DK_SECAM_A2MONO        14
+#define L_SECAM_NICAM          15
+#define LC_SECAM_NICAM         16
+#define DTV6                   17
+#define DTV8                   18
+#define DTV7_8                 19
+#define DTV7                   20
+#define FM_Radio_INPUT2        21
+#define FM_Radio_INPUT1        22
+#define FM_Radio_INPUT1_MONO   23
+
+static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
+       {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020},
+       {"M/N-NTSC/PAL-A2",   0x0600, 0x8020},
+       {"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020},
+       {"M/N-NTSC/PAL-Mono", 0x0478, 0x8020},
+       {"B/G-PAL-A2",        0x0A00, 0x8049},
+       {"B/G-PAL-NICAM",     0x0C04, 0x8049},
+       {"B/G-PAL-MONO",      0x0878, 0x8059},
+       {"I-PAL-NICAM",       0x1080, 0x8009},
+       {"I-PAL-NICAM-MONO",  0x0E78, 0x8009},
+       {"D/K-PAL-A2",        0x1600, 0x8009},
+       {"D/K-PAL-NICAM",     0x0E80, 0x8009},
+       {"D/K-PAL-MONO",      0x1478, 0x8009},
+       {"D/K-SECAM-A2 DK1",  0x1200, 0x8009},
+       {"D/K-SECAM-A2 L/DK3", 0x0E00, 0x8009},
+       {"D/K-SECAM-A2 MONO", 0x1478, 0x8009},
+       {"L-SECAM-NICAM",     0x8E82, 0x0009},
+       {"L'-SECAM-NICAM",    0x8E82, 0x4009},
+       {"DTV6",              0x00C0, 0x8002},
+       {"DTV8",              0x00C0, 0x800B},
+       {"DTV7/8",            0x00C0, 0x801B},
+       {"DTV7",              0x00C0, 0x8007},
+       {"FM Radio-INPUT2",   0x9802, 0x9002},
+       {"FM Radio-INPUT1",   0x0208, 0x9002},
+       {"FM Radio-INPUT1_MONO", 0x0278, 0x9002}
+};
+
+
+struct xc5000_fw_cfg {
+       char *name;
+       u16 size;
+       u16 pll_reg;
+       u8 init_status_supported;
+       u8 fw_checksum_supported;
+};
+
+#define XC5000A_FIRMWARE "dvb-fe-xc5000-1.6.114.fw"
+static const struct xc5000_fw_cfg xc5000a_1_6_114 = {
+       .name = XC5000A_FIRMWARE,
+       .size = 12401,
+       .pll_reg = 0x806c,
+};
+
+#define XC5000C_FIRMWARE "dvb-fe-xc5000c-4.1.30.7.fw"
+static const struct xc5000_fw_cfg xc5000c_41_024_5 = {
+       .name = XC5000C_FIRMWARE,
+       .size = 16497,
+       .pll_reg = 0x13,
+       .init_status_supported = 1,
+       .fw_checksum_supported = 1,
+};
+
+static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id)
+{
+       switch (chip_id) {
+       default:
+       case XC5000A:
+               return &xc5000a_1_6_114;
+       case XC5000C:
+               return &xc5000c_41_024_5;
+       }
+}
+
+static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force);
+static int xc5000_is_firmware_loaded(struct dvb_frontend *fe);
+static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val);
+static int xc5000_TunerReset(struct dvb_frontend *fe);
+
+static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
+{
+       struct i2c_msg msg = { .addr = priv->i2c_props.addr,
+                              .flags = 0, .buf = buf, .len = len };
+
+       if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
+               printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n", len);
+               return XC_RESULT_I2C_WRITE_FAILURE;
+       }
+       return XC_RESULT_SUCCESS;
+}
+
+#if 0
+/* This routine is never used because the only time we read data from the
+   i2c bus is when we read registers, and we want that to be an atomic i2c
+   transaction in case we are on a multi-master bus */
+static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
+{
+       struct i2c_msg msg = { .addr = priv->i2c_props.addr,
+               .flags = I2C_M_RD, .buf = buf, .len = len };
+
+       if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
+               printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", len);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+#endif
+
+static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val)
+{
+       u8 buf[2] = { reg >> 8, reg & 0xff };
+       u8 bval[2] = { 0, 0 };
+       struct i2c_msg msg[2] = {
+               { .addr = priv->i2c_props.addr,
+                       .flags = 0, .buf = &buf[0], .len = 2 },
+               { .addr = priv->i2c_props.addr,
+                       .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
+       };
+
+       if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
+               printk(KERN_WARNING "xc5000: I2C read failed\n");
+               return -EREMOTEIO;
+       }
+
+       *val = (bval[0] << 8) | bval[1];
+       return XC_RESULT_SUCCESS;
+}
+
+static void xc_wait(int wait_ms)
+{
+       msleep(wait_ms);
+}
+
+static int xc5000_TunerReset(struct dvb_frontend *fe)
+{
+       struct xc5000_priv *priv = fe->tuner_priv;
+       int ret;
+
+       dprintk(1, "%s()\n", __func__);
+
+       if (fe->callback) {
+               ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
+                                          fe->dvb->priv :
+                                          priv->i2c_props.adap->algo_data,
+                                          DVB_FRONTEND_COMPONENT_TUNER,
+                                          XC5000_TUNER_RESET, 0);
+               if (ret) {
+                       printk(KERN_ERR "xc5000: reset failed\n");
+                       return XC_RESULT_RESET_FAILURE;
+               }
+       } else {
+               printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n");
+               return XC_RESULT_RESET_FAILURE;
+       }
+       return XC_RESULT_SUCCESS;
+}
+
+static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData)
+{
+       u8 buf[4];
+       int WatchDogTimer = 100;
+       int result;
+
+       buf[0] = (regAddr >> 8) & 0xFF;
+       buf[1] = regAddr & 0xFF;
+       buf[2] = (i2cData >> 8) & 0xFF;
+       buf[3] = i2cData & 0xFF;
+       result = xc_send_i2c_data(priv, buf, 4);
+       if (result == XC_RESULT_SUCCESS) {
+               /* wait for busy flag to clear */
+               while ((WatchDogTimer > 0) && (result == XC_RESULT_SUCCESS)) {
+                       result = xc5000_readreg(priv, XREG_BUSY, (u16 *)buf);
+                       if (result == XC_RESULT_SUCCESS) {
+                               if ((buf[0] == 0) && (buf[1] == 0)) {
+                                       /* busy flag cleared */
+                                       break;
+                               } else {
+                                       xc_wait(5); /* wait 5 ms */
+                                       WatchDogTimer--;
+                               }
+                       }
+               }
+       }
+       if (WatchDogTimer <= 0)
+               result = XC_RESULT_I2C_WRITE_FAILURE;
+
+       return result;
+}
+
+static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
+{
+       struct xc5000_priv *priv = fe->tuner_priv;
+
+       int i, nbytes_to_send, result;
+       unsigned int len, pos, index;
+       u8 buf[XC_MAX_I2C_WRITE_LENGTH];
+
+       index = 0;
+       while ((i2c_sequence[index] != 0xFF) ||
+               (i2c_sequence[index + 1] != 0xFF)) {
+               len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
+               if (len == 0x0000) {
+                       /* RESET command */
+                       result = xc5000_TunerReset(fe);
+                       index += 2;
+                       if (result != XC_RESULT_SUCCESS)
+                               return result;
+               } else if (len & 0x8000) {
+                       /* WAIT command */
+                       xc_wait(len & 0x7FFF);
+                       index += 2;
+               } else {
+                       /* Send i2c data whilst ensuring individual transactions
+                        * do not exceed XC_MAX_I2C_WRITE_LENGTH bytes.
+                        */
+                       index += 2;
+                       buf[0] = i2c_sequence[index];
+                       buf[1] = i2c_sequence[index + 1];
+                       pos = 2;
+                       while (pos < len) {
+                               if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
+                                       nbytes_to_send =
+                                               XC_MAX_I2C_WRITE_LENGTH;
+                               else
+                                       nbytes_to_send = (len - pos + 2);
+                               for (i = 2; i < nbytes_to_send; i++) {
+                                       buf[i] = i2c_sequence[index + pos +
+                                               i - 2];
+                               }
+                               result = xc_send_i2c_data(priv, buf,
+                                       nbytes_to_send);
+
+                               if (result != XC_RESULT_SUCCESS)
+                                       return result;
+
+                               pos += nbytes_to_send - 2;
+                       }
+                       index += len;
+               }
+       }
+       return XC_RESULT_SUCCESS;
+}
+
+static int xc_initialize(struct xc5000_priv *priv)
+{
+       dprintk(1, "%s()\n", __func__);
+       return xc_write_reg(priv, XREG_INIT, 0);
+}
+
+static int xc_SetTVStandard(struct xc5000_priv *priv,
+       u16 VideoMode, u16 AudioMode)
+{
+       int ret;
+       dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, VideoMode, AudioMode);
+       dprintk(1, "%s() Standard = %s\n",
+               __func__,
+               XC5000_Standard[priv->video_standard].Name);
+
+       ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode);
+       if (ret == XC_RESULT_SUCCESS)
+               ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode);
+
+       return ret;
+}
+
+static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode)
+{
+       dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
+               rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
+
+       if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
+               rf_mode = XC_RF_MODE_CABLE;
+               printk(KERN_ERR
+                       "%s(), Invalid mode, defaulting to CABLE",
+                       __func__);
+       }
+       return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
+}
+
+static const struct dvb_tuner_ops xc5000_tuner_ops;
+
+static int xc_set_RF_frequency(struct xc5000_priv *priv, u32 freq_hz)
+{
+       u16 freq_code;
+
+       dprintk(1, "%s(%u)\n", __func__, freq_hz);
+
+       if ((freq_hz > xc5000_tuner_ops.info.frequency_max) ||
+               (freq_hz < xc5000_tuner_ops.info.frequency_min))
+               return XC_RESULT_OUT_OF_RANGE;
+
+       freq_code = (u16)(freq_hz / 15625);
+
+       /* Starting in firmware version 1.1.44, Xceive recommends using the
+          FINERFREQ for all normal tuning (the doc indicates reg 0x03 should
+          only be used for fast scanning for channel lock) */
+       return xc_write_reg(priv, XREG_FINERFREQ, freq_code);
+}
+
+
+static int xc_set_IF_frequency(struct xc5000_priv *priv, u32 freq_khz)
+{
+       u32 freq_code = (freq_khz * 1024)/1000;
+       dprintk(1, "%s(freq_khz = %d) freq_code = 0x%x\n",
+               __func__, freq_khz, freq_code);
+
+       return xc_write_reg(priv, XREG_IF_OUT, freq_code);
+}
+
+
+static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope)
+{
+       return xc5000_readreg(priv, XREG_ADC_ENV, adc_envelope);
+}
+
+static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz)
+{
+       int result;
+       u16 regData;
+       u32 tmp;
+
+       result = xc5000_readreg(priv, XREG_FREQ_ERROR, &regData);
+       if (result != XC_RESULT_SUCCESS)
+               return result;
+
+       tmp = (u32)regData;
+       (*freq_error_hz) = (tmp * 15625) / 1000;
+       return result;
+}
+
+static int xc_get_lock_status(struct xc5000_priv *priv, u16 *lock_status)
+{
+       return xc5000_readreg(priv, XREG_LOCK, lock_status);
+}
+
+static int xc_get_version(struct xc5000_priv *priv,
+       u8 *hw_majorversion, u8 *hw_minorversion,
+       u8 *fw_majorversion, u8 *fw_minorversion)
+{
+       u16 data;
+       int result;
+
+       result = xc5000_readreg(priv, XREG_VERSION, &data);
+       if (result != XC_RESULT_SUCCESS)
+               return result;
+
+       (*hw_majorversion) = (data >> 12) & 0x0F;
+       (*hw_minorversion) = (data >>  8) & 0x0F;
+       (*fw_majorversion) = (data >>  4) & 0x0F;
+       (*fw_minorversion) = data & 0x0F;
+
+       return 0;
+}
+
+static int xc_get_buildversion(struct xc5000_priv *priv, u16 *buildrev)
+{
+       return xc5000_readreg(priv, XREG_BUILD, buildrev);
+}
+
+static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz)
+{
+       u16 regData;
+       int result;
+
+       result = xc5000_readreg(priv, XREG_HSYNC_FREQ, &regData);
+       if (result != XC_RESULT_SUCCESS)
+               return result;
+
+       (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
+       return result;
+}
+
+static int xc_get_frame_lines(struct xc5000_priv *priv, u16 *frame_lines)
+{
+       return xc5000_readreg(priv, XREG_FRAME_LINES, frame_lines);
+}
+
+static int xc_get_quality(struct xc5000_priv *priv, u16 *quality)
+{
+       return xc5000_readreg(priv, XREG_QUALITY, quality);
+}
+
+static int xc_get_analogsnr(struct xc5000_priv *priv, u16 *snr)
+{
+       return xc5000_readreg(priv, XREG_SNR, snr);
+}
+
+static int xc_get_totalgain(struct xc5000_priv *priv, u16 *totalgain)
+{
+       return xc5000_readreg(priv, XREG_TOTALGAIN, totalgain);
+}
+
+static u16 WaitForLock(struct xc5000_priv *priv)
+{
+       u16 lockState = 0;
+       int watchDogCount = 40;
+
+       while ((lockState == 0) && (watchDogCount > 0)) {
+               xc_get_lock_status(priv, &lockState);
+               if (lockState != 1) {
+                       xc_wait(5);
+                       watchDogCount--;
+               }
+       }
+       return lockState;
+}
+
+#define XC_TUNE_ANALOG  0
+#define XC_TUNE_DIGITAL 1
+static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode)
+{
+       int found = 0;
+
+       dprintk(1, "%s(%u)\n", __func__, freq_hz);
+
+       if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS)
+               return 0;
+
+       if (mode == XC_TUNE_ANALOG) {
+               if (WaitForLock(priv) == 1)
+                       found = 1;
+       }
+
+       return found;
+}
+
+static int xc_set_xtal(struct dvb_frontend *fe)
+{
+       struct xc5000_priv *priv = fe->tuner_priv;
+       int ret = XC_RESULT_SUCCESS;
+
+       switch (priv->chip_id) {
+       default:
+       case XC5000A:
+               /* 32.000 MHz xtal is default */
+               break;
+       case XC5000C:
+               switch (priv->xtal_khz) {
+               default:
+               case 32000:
+                       /* 32.000 MHz xtal is default */
+                       break;
+               case 31875:
+                       /* 31.875 MHz xtal configuration */
+                       ret = xc_write_reg(priv, 0x000f, 0x8081);
+                       break;
+               }
+               break;
+       }
+       return ret;
+}
+
+static int xc5000_fwupload(struct dvb_frontend *fe)
+{
+       struct xc5000_priv *priv = fe->tuner_priv;
+       const struct firmware *fw;
+       int ret;
+       const struct xc5000_fw_cfg *desired_fw =
+               xc5000_assign_firmware(priv->chip_id);
+       priv->pll_register_no = desired_fw->pll_reg;
+       priv->init_status_supported = desired_fw->init_status_supported;
+       priv->fw_checksum_supported = desired_fw->fw_checksum_supported;
+
+       /* request the firmware, this will block and timeout */
+       printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
+               desired_fw->name);
+
+       ret = request_firmware(&fw, desired_fw->name,
+               priv->i2c_props.adap->dev.parent);
+       if (ret) {
+               printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
+               ret = XC_RESULT_RESET_FAILURE;
+               goto out;
+       } else {
+               printk(KERN_DEBUG "xc5000: firmware read %Zu bytes.\n",
+                      fw->size);
+               ret = XC_RESULT_SUCCESS;
+       }
+
+       if (fw->size != desired_fw->size) {
+               printk(KERN_ERR "xc5000: firmware incorrect size\n");
+               ret = XC_RESULT_RESET_FAILURE;
+       } else {
+               printk(KERN_INFO "xc5000: firmware uploading...\n");
+               ret = xc_load_i2c_sequence(fe,  fw->data);
+               if (XC_RESULT_SUCCESS == ret)
+                       ret = xc_set_xtal(fe);
+               if (XC_RESULT_SUCCESS == ret)
+                       printk(KERN_INFO "xc5000: firmware upload complete...\n");
+               else
+                       printk(KERN_ERR "xc5000: firmware upload failed...\n");
+       }
+
+out:
+       release_firmware(fw);
+       return ret;
+}
+
+static void xc_debug_dump(struct xc5000_priv *priv)
+{
+       u16 adc_envelope;
+       u32 freq_error_hz = 0;
+       u16 lock_status;
+       u32 hsync_freq_hz = 0;
+       u16 frame_lines;
+       u16 quality;
+       u16 snr;
+       u16 totalgain;
+       u8 hw_majorversion = 0, hw_minorversion = 0;
+       u8 fw_majorversion = 0, fw_minorversion = 0;
+       u16 fw_buildversion = 0;
+       u16 regval;
+
+       /* Wait for stats to stabilize.
+        * Frame Lines needs two frame times after initial lock
+        * before it is valid.
+        */
+       xc_wait(100);
+
+       xc_get_ADC_Envelope(priv,  &adc_envelope);
+       dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
+
+       xc_get_frequency_error(priv, &freq_error_hz);
+       dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
+
+       xc_get_lock_status(priv,  &lock_status);
+       dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
+               lock_status);
+
+       xc_get_version(priv,  &hw_majorversion, &hw_minorversion,
+               &fw_majorversion, &fw_minorversion);
+       xc_get_buildversion(priv,  &fw_buildversion);
+       dprintk(1, "*** HW: V%d.%d, FW: V %d.%d.%d\n",
+               hw_majorversion, hw_minorversion,
+               fw_majorversion, fw_minorversion, fw_buildversion);
+
+       xc_get_hsync_freq(priv,  &hsync_freq_hz);
+       dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz);
+
+       xc_get_frame_lines(priv,  &frame_lines);
+       dprintk(1, "*** Frame lines = %d\n", frame_lines);
+
+       xc_get_quality(priv,  &quality);
+       dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality & 0x07);
+
+       xc_get_analogsnr(priv,  &snr);
+       dprintk(1, "*** Unweighted analog SNR = %d dB\n", snr & 0x3f);
+
+       xc_get_totalgain(priv,  &totalgain);
+       dprintk(1, "*** Total gain = %d.%d dB\n", totalgain / 256,
+               (totalgain % 256) * 100 / 256);
+
+       if (priv->pll_register_no) {
+               xc5000_readreg(priv, priv->pll_register_no, &regval);
+               dprintk(1, "*** PLL lock status = 0x%04x\n", regval);
+       }
+}
+
+static int xc5000_set_params(struct dvb_frontend *fe)
+{
+       int ret, b;
+       struct xc5000_priv *priv = fe->tuner_priv;
+       u32 bw = fe->dtv_property_cache.bandwidth_hz;
+       u32 freq = fe->dtv_property_cache.frequency;
+       u32 delsys  = fe->dtv_property_cache.delivery_system;
+
+       if (xc_load_fw_and_init_tuner(fe, 0) != XC_RESULT_SUCCESS) {
+               dprintk(1, "Unable to load firmware and init tuner\n");
+               return -EINVAL;
+       }
+
+       dprintk(1, "%s() frequency=%d (Hz)\n", __func__, freq);
+
+       switch (delsys) {
+       case SYS_ATSC:
+               dprintk(1, "%s() VSB modulation\n", __func__);
+               priv->rf_mode = XC_RF_MODE_AIR;
+               priv->freq_hz = freq - 1750000;
+               priv->video_standard = DTV6;
+               break;
+       case SYS_DVBC_ANNEX_B:
+               dprintk(1, "%s() QAM modulation\n", __func__);
+               priv->rf_mode = XC_RF_MODE_CABLE;
+               priv->freq_hz = freq - 1750000;
+               priv->video_standard = DTV6;
+               break;
+       case SYS_ISDBT:
+               /* All ISDB-T are currently for 6 MHz bw */
+               if (!bw)
+                       bw = 6000000;
+               /* fall to OFDM handling */
+       case SYS_DMBTH:
+       case SYS_DVBT:
+       case SYS_DVBT2:
+               dprintk(1, "%s() OFDM\n", __func__);
+               switch (bw) {
+               case 6000000:
+                       priv->video_standard = DTV6;
+                       priv->freq_hz = freq - 1750000;
+                       break;
+               case 7000000:
+                       priv->video_standard = DTV7;
+                       priv->freq_hz = freq - 2250000;
+                       break;
+               case 8000000:
+                       priv->video_standard = DTV8;
+                       priv->freq_hz = freq - 2750000;
+                       break;
+               default:
+                       printk(KERN_ERR "xc5000 bandwidth not set!\n");
+                       return -EINVAL;
+               }
+               priv->rf_mode = XC_RF_MODE_AIR;
+       case SYS_DVBC_ANNEX_A:
+       case SYS_DVBC_ANNEX_C:
+               dprintk(1, "%s() QAM modulation\n", __func__);
+               priv->rf_mode = XC_RF_MODE_CABLE;
+               if (bw <= 6000000) {
+                       priv->video_standard = DTV6;
+                       priv->freq_hz = freq - 1750000;
+                       b = 6;
+               } else if (bw <= 7000000) {
+                       priv->video_standard = DTV7;
+                       priv->freq_hz = freq - 2250000;
+                       b = 7;
+               } else {
+                       priv->video_standard = DTV7_8;
+                       priv->freq_hz = freq - 2750000;
+                       b = 8;
+               }
+               dprintk(1, "%s() Bandwidth %dMHz (%d)\n", __func__,
+                       b, bw);
+               break;
+       default:
+               printk(KERN_ERR "xc5000: delivery system is not supported!\n");
+               return -EINVAL;
+       }
+
+       dprintk(1, "%s() frequency=%d (compensated to %d)\n",
+               __func__, freq, priv->freq_hz);
+
+       ret = xc_SetSignalSource(priv, priv->rf_mode);
+       if (ret != XC_RESULT_SUCCESS) {
+               printk(KERN_ERR
+                       "xc5000: xc_SetSignalSource(%d) failed\n",
+                       priv->rf_mode);
+               return -EREMOTEIO;
+       }
+
+       ret = xc_SetTVStandard(priv,
+               XC5000_Standard[priv->video_standard].VideoMode,
+               XC5000_Standard[priv->video_standard].AudioMode);
+       if (ret != XC_RESULT_SUCCESS) {
+               printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
+               return -EREMOTEIO;
+       }
+
+       ret = xc_set_IF_frequency(priv, priv->if_khz);
+       if (ret != XC_RESULT_SUCCESS) {
+               printk(KERN_ERR "xc5000: xc_Set_IF_frequency(%d) failed\n",
+                      priv->if_khz);
+               return -EIO;
+       }
+
+       xc_write_reg(priv, XREG_OUTPUT_AMP, 0x8a);
+
+       xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
+
+       if (debug)
+               xc_debug_dump(priv);
+
+       priv->bandwidth = bw;
+
+       return 0;
+}
+
+static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
+{
+       struct xc5000_priv *priv = fe->tuner_priv;
+       int ret;
+       u16 id;
+
+       ret = xc5000_readreg(priv, XREG_PRODUCT_ID, &id);
+       if (ret == XC_RESULT_SUCCESS) {
+               if (id == XC_PRODUCT_ID_FW_NOT_LOADED)
+                       ret = XC_RESULT_RESET_FAILURE;
+               else
+                       ret = XC_RESULT_SUCCESS;
+       }
+
+       dprintk(1, "%s() returns %s id = 0x%x\n", __func__,
+               ret == XC_RESULT_SUCCESS ? "True" : "False", id);
+       return ret;
+}
+
+static int xc5000_set_tv_freq(struct dvb_frontend *fe,
+       struct analog_parameters *params)
+{
+       struct xc5000_priv *priv = fe->tuner_priv;
+       u16 pll_lock_status;
+       int ret;
+
+       dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
+               __func__, params->frequency);
+
+       /* Fix me: it could be air. */
+       priv->rf_mode = params->mode;
+       if (params->mode > XC_RF_MODE_CABLE)
+               priv->rf_mode = XC_RF_MODE_CABLE;
+
+       /* params->frequency is in units of 62.5khz */
+       priv->freq_hz = params->frequency * 62500;
+
+       /* FIX ME: Some video standards may have several possible audio
+                  standards. We simply default to one of them here.
+        */
+       if (params->std & V4L2_STD_MN) {
+               /* default to BTSC audio standard */
+               priv->video_standard = MN_NTSC_PAL_BTSC;
+               goto tune_channel;
+       }
+
+       if (params->std & V4L2_STD_PAL_BG) {
+               /* default to NICAM audio standard */
+               priv->video_standard = BG_PAL_NICAM;
+               goto tune_channel;
+       }
+
+       if (params->std & V4L2_STD_PAL_I) {
+               /* default to NICAM audio standard */
+               priv->video_standard = I_PAL_NICAM;
+               goto tune_channel;
+       }
+
+       if (params->std & V4L2_STD_PAL_DK) {
+               /* default to NICAM audio standard */
+               priv->video_standard = DK_PAL_NICAM;
+               goto tune_channel;
+       }
+
+       if (params->std & V4L2_STD_SECAM_DK) {
+               /* default to A2 DK1 audio standard */
+               priv->video_standard = DK_SECAM_A2DK1;
+               goto tune_channel;
+       }
+
+       if (params->std & V4L2_STD_SECAM_L) {
+               priv->video_standard = L_SECAM_NICAM;
+               goto tune_channel;
+       }
+
+       if (params->std & V4L2_STD_SECAM_LC) {
+               priv->video_standard = LC_SECAM_NICAM;
+               goto tune_channel;
+       }
+
+tune_channel:
+       ret = xc_SetSignalSource(priv, priv->rf_mode);
+       if (ret != XC_RESULT_SUCCESS) {
+               printk(KERN_ERR
+                       "xc5000: xc_SetSignalSource(%d) failed\n",
+                       priv->rf_mode);
+               return -EREMOTEIO;
+       }
+
+       ret = xc_SetTVStandard(priv,
+               XC5000_Standard[priv->video_standard].VideoMode,
+               XC5000_Standard[priv->video_standard].AudioMode);
+       if (ret != XC_RESULT_SUCCESS) {
+               printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
+               return -EREMOTEIO;
+       }
+
+       xc_write_reg(priv, XREG_OUTPUT_AMP, 0x09);
+
+       xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
+
+       if (debug)
+               xc_debug_dump(priv);
+
+       if (priv->pll_register_no != 0) {
+               msleep(20);
+               xc5000_readreg(priv, priv->pll_register_no, &pll_lock_status);
+               if (pll_lock_status > 63) {
+                       /* PLL is unlocked, force reload of the firmware */
+                       dprintk(1, "xc5000: PLL not locked (0x%x).  Reloading...\n",
+                               pll_lock_status);
+                       if (xc_load_fw_and_init_tuner(fe, 1) != XC_RESULT_SUCCESS) {
+                               printk(KERN_ERR "xc5000: Unable to reload fw\n");
+                               return -EREMOTEIO;
+                       }
+                       goto tune_channel;
+               }
+       }
+
+       return 0;
+}
+
+static int xc5000_set_radio_freq(struct dvb_frontend *fe,
+       struct analog_parameters *params)
+{
+       struct xc5000_priv *priv = fe->tuner_priv;
+       int ret = -EINVAL;
+       u8 radio_input;
+
+       dprintk(1, "%s() frequency=%d (in units of khz)\n",
+               __func__, params->frequency);
+
+       if (priv->radio_input == XC5000_RADIO_NOT_CONFIGURED) {
+               dprintk(1, "%s() radio input not configured\n", __func__);
+               return -EINVAL;
+       }
+
+       if (priv->radio_input == XC5000_RADIO_FM1)
+               radio_input = FM_Radio_INPUT1;
+       else if  (priv->radio_input == XC5000_RADIO_FM2)
+               radio_input = FM_Radio_INPUT2;
+       else if  (priv->radio_input == XC5000_RADIO_FM1_MONO)
+               radio_input = FM_Radio_INPUT1_MONO;
+       else {
+               dprintk(1, "%s() unknown radio input %d\n", __func__,
+                       priv->radio_input);
+               return -EINVAL;
+       }
+
+       priv->freq_hz = params->frequency * 125 / 2;
+
+       priv->rf_mode = XC_RF_MODE_AIR;
+
+       ret = xc_SetTVStandard(priv, XC5000_Standard[radio_input].VideoMode,
+                              XC5000_Standard[radio_input].AudioMode);
+
+       if (ret != XC_RESULT_SUCCESS) {
+               printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
+               return -EREMOTEIO;
+       }
+
+       ret = xc_SetSignalSource(priv, priv->rf_mode);
+       if (ret != XC_RESULT_SUCCESS) {
+               printk(KERN_ERR
+                       "xc5000: xc_SetSignalSource(%d) failed\n",
+                       priv->rf_mode);
+               return -EREMOTEIO;
+       }
+
+       if ((priv->radio_input == XC5000_RADIO_FM1) ||
+                               (priv->radio_input == XC5000_RADIO_FM2))
+               xc_write_reg(priv, XREG_OUTPUT_AMP, 0x09);
+       else if  (priv->radio_input == XC5000_RADIO_FM1_MONO)
+               xc_write_reg(priv, XREG_OUTPUT_AMP, 0x06);
+
+       xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
+
+       return 0;
+}
+
+static int xc5000_set_analog_params(struct dvb_frontend *fe,
+                            struct analog_parameters *params)
+{
+       struct xc5000_priv *priv = fe->tuner_priv;
+       int ret = -EINVAL;
+
+       if (priv->i2c_props.adap == NULL)
+               return -EINVAL;
+
+       if (xc_load_fw_and_init_tuner(fe, 0) != XC_RESULT_SUCCESS) {
+               dprintk(1, "Unable to load firmware and init tuner\n");
+               return -EINVAL;
+       }
+
+       switch (params->mode) {
+       case V4L2_TUNER_RADIO:
+               ret = xc5000_set_radio_freq(fe, params);
+               break;
+       case V4L2_TUNER_ANALOG_TV:
+       case V4L2_TUNER_DIGITAL_TV:
+               ret = xc5000_set_tv_freq(fe, params);
+               break;
+       }
+
+       return ret;
+}
+
+
+static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq)
+{
+       struct xc5000_priv *priv = fe->tuner_priv;
+       dprintk(1, "%s()\n", __func__);
+       *freq = priv->freq_hz;
+       return 0;
+}
+
+static int xc5000_get_if_frequency(struct dvb_frontend *fe, u32 *freq)
+{
+       struct xc5000_priv *priv = fe->tuner_priv;
+       dprintk(1, "%s()\n", __func__);
+       *freq = priv->if_khz * 1000;
+       return 0;
+}
+
+static int xc5000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
+{
+       struct xc5000_priv *priv = fe->tuner_priv;
+       dprintk(1, "%s()\n", __func__);
+
+       *bw = priv->bandwidth;
+       return 0;
+}
+
+static int xc5000_get_status(struct dvb_frontend *fe, u32 *status)
+{
+       struct xc5000_priv *priv = fe->tuner_priv;
+       u16 lock_status = 0;
+
+       xc_get_lock_status(priv, &lock_status);
+
+       dprintk(1, "%s() lock_status = 0x%08x\n", __func__, lock_status);
+
+       *status = lock_status;
+
+       return 0;
+}
+
+static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
+{
+       struct xc5000_priv *priv = fe->tuner_priv;
+       int ret = XC_RESULT_SUCCESS;
+       u16 pll_lock_status;
+       u16 fw_ck;
+
+       if (force || xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
+
+fw_retry:
+
+               ret = xc5000_fwupload(fe);
+               if (ret != XC_RESULT_SUCCESS)
+                       return ret;
+
+               msleep(20);
+
+               if (priv->fw_checksum_supported) {
+                       if (xc5000_readreg(priv, XREG_FW_CHECKSUM, &fw_ck)
+                           != XC_RESULT_SUCCESS) {
+                               dprintk(1, "%s() FW checksum reading failed.\n",
+                                       __func__);
+                               goto fw_retry;
+                       }
+
+                       if (fw_ck == 0) {
+                               dprintk(1, "%s() FW checksum failed = 0x%04x\n",
+                                       __func__, fw_ck);
+                               goto fw_retry;
+                       }
+               }
+
+               /* Start the tuner self-calibration process */
+               ret |= xc_initialize(priv);
+
+               if (ret != XC_RESULT_SUCCESS)
+                       goto fw_retry;
+
+               /* Wait for calibration to complete.
+                * We could continue but XC5000 will clock stretch subsequent
+                * I2C transactions until calibration is complete.  This way we
+                * don't have to rely on clock stretching working.
+                */
+               xc_wait(100);
+
+               if (priv->init_status_supported) {
+                       if (xc5000_readreg(priv, XREG_INIT_STATUS, &fw_ck) != XC_RESULT_SUCCESS) {
+                               dprintk(1, "%s() FW failed reading init status.\n",
+                                       __func__);
+                               goto fw_retry;
+                       }
+
+                       if (fw_ck == 0) {
+                               dprintk(1, "%s() FW init status failed = 0x%04x\n", __func__, fw_ck);
+                               goto fw_retry;
+                       }
+               }
+
+               if (priv->pll_register_no) {
+                       xc5000_readreg(priv, priv->pll_register_no,
+                                      &pll_lock_status);
+                       if (pll_lock_status > 63) {
+                               /* PLL is unlocked, force reload of the firmware */
+                               printk(KERN_ERR "xc5000: PLL not running after fwload.\n");
+                               goto fw_retry;
+                       }
+               }
+
+               /* Default to "CABLE" mode */
+               ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
+       }
+
+       return ret;
+}
+
+static int xc5000_sleep(struct dvb_frontend *fe)
+{
+       int ret;
+
+       dprintk(1, "%s()\n", __func__);
+
+       /* Avoid firmware reload on slow devices */
+       if (no_poweroff)
+               return 0;
+
+       /* According to Xceive technical support, the "powerdown" register
+          was removed in newer versions of the firmware.  The "supported"
+          way to sleep the tuner is to pull the reset pin low for 10ms */
+       ret = xc5000_TunerReset(fe);
+       if (ret != XC_RESULT_SUCCESS) {
+               printk(KERN_ERR
+                       "xc5000: %s() unable to shutdown tuner\n",
+                       __func__);
+               return -EREMOTEIO;
+       } else
+               return XC_RESULT_SUCCESS;
+}
+
+static int xc5000_init(struct dvb_frontend *fe)
+{
+       struct xc5000_priv *priv = fe->tuner_priv;
+       dprintk(1, "%s()\n", __func__);
+
+       if (xc_load_fw_and_init_tuner(fe, 0) != XC_RESULT_SUCCESS) {
+               printk(KERN_ERR "xc5000: Unable to initialise tuner\n");
+               return -EREMOTEIO;
+       }
+
+       if (debug)
+               xc_debug_dump(priv);
+
+       return 0;
+}
+
+static int xc5000_release(struct dvb_frontend *fe)
+{
+       struct xc5000_priv *priv = fe->tuner_priv;
+
+       dprintk(1, "%s()\n", __func__);
+
+       mutex_lock(&xc5000_list_mutex);
+
+       if (priv)
+               hybrid_tuner_release_state(priv);
+
+       mutex_unlock(&xc5000_list_mutex);
+
+       fe->tuner_priv = NULL;
+
+       return 0;
+}
+
+static int xc5000_set_config(struct dvb_frontend *fe, void *priv_cfg)
+{
+       struct xc5000_priv *priv = fe->tuner_priv;
+       struct xc5000_config *p = priv_cfg;
+
+       dprintk(1, "%s()\n", __func__);
+
+       if (p->if_khz)
+               priv->if_khz = p->if_khz;
+
+       if (p->radio_input)
+               priv->radio_input = p->radio_input;
+
+       return 0;
+}
+
+
+static const struct dvb_tuner_ops xc5000_tuner_ops = {
+       .info = {
+               .name           = "Xceive XC5000",
+               .frequency_min  =    1000000,
+               .frequency_max  = 1023000000,
+               .frequency_step =      50000,
+       },
+
+       .release           = xc5000_release,
+       .init              = xc5000_init,
+       .sleep             = xc5000_sleep,
+
+       .set_config        = xc5000_set_config,
+       .set_params        = xc5000_set_params,
+       .set_analog_params = xc5000_set_analog_params,
+       .get_frequency     = xc5000_get_frequency,
+       .get_if_frequency  = xc5000_get_if_frequency,
+       .get_bandwidth     = xc5000_get_bandwidth,
+       .get_status        = xc5000_get_status
+};
+
+struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
+                                  struct i2c_adapter *i2c,
+                                  const struct xc5000_config *cfg)
+{
+       struct xc5000_priv *priv = NULL;
+       int instance;
+       u16 id = 0;
+
+       dprintk(1, "%s(%d-%04x)\n", __func__,
+               i2c ? i2c_adapter_id(i2c) : -1,
+               cfg ? cfg->i2c_address : -1);
+
+       mutex_lock(&xc5000_list_mutex);
+
+       instance = hybrid_tuner_request_state(struct xc5000_priv, priv,
+                                             hybrid_tuner_instance_list,
+                                             i2c, cfg->i2c_address, "xc5000");
+       switch (instance) {
+       case 0:
+               goto fail;
+               break;
+       case 1:
+               /* new tuner instance */
+               priv->bandwidth = 6000000;
+               fe->tuner_priv = priv;
+               break;
+       default:
+               /* existing tuner instance */
+               fe->tuner_priv = priv;
+               break;
+       }
+
+       if (priv->if_khz == 0) {
+               /* If the IF hasn't been set yet, use the value provided by
+                  the caller (occurs in hybrid devices where the analog
+                  call to xc5000_attach occurs before the digital side) */
+               priv->if_khz = cfg->if_khz;
+       }
+
+       if (priv->xtal_khz == 0)
+               priv->xtal_khz = cfg->xtal_khz;
+
+       if (priv->radio_input == 0)
+               priv->radio_input = cfg->radio_input;
+
+       /* don't override chip id if it's already been set
+          unless explicitly specified */
+       if ((priv->chip_id == 0) || (cfg->chip_id))
+               /* use default chip id if none specified, set to 0 so
+                  it can be overridden if this is a hybrid driver */
+               priv->chip_id = (cfg->chip_id) ? cfg->chip_id : 0;
+
+       /* Check if firmware has been loaded. It is possible that another
+          instance of the driver has loaded the firmware.
+        */
+       if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != XC_RESULT_SUCCESS)
+               goto fail;
+
+       switch (id) {
+       case XC_PRODUCT_ID_FW_LOADED:
+               printk(KERN_INFO
+                       "xc5000: Successfully identified at address 0x%02x\n",
+                       cfg->i2c_address);
+               printk(KERN_INFO
+                       "xc5000: Firmware has been loaded previously\n");
+               break;
+       case XC_PRODUCT_ID_FW_NOT_LOADED:
+               printk(KERN_INFO
+                       "xc5000: Successfully identified at address 0x%02x\n",
+                       cfg->i2c_address);
+               printk(KERN_INFO
+                       "xc5000: Firmware has not been loaded previously\n");
+               break;
+       default:
+               printk(KERN_ERR
+                       "xc5000: Device not found at addr 0x%02x (0x%x)\n",
+                       cfg->i2c_address, id);
+               goto fail;
+       }
+
+       mutex_unlock(&xc5000_list_mutex);
+
+       memcpy(&fe->ops.tuner_ops, &xc5000_tuner_ops,
+               sizeof(struct dvb_tuner_ops));
+
+       return fe;
+fail:
+       mutex_unlock(&xc5000_list_mutex);
+
+       xc5000_release(fe);
+       return NULL;
+}
+EXPORT_SYMBOL(xc5000_attach);
+
+MODULE_AUTHOR("Steven Toth");
+MODULE_DESCRIPTION("Xceive xc5000 silicon tuner driver");
+MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(XC5000A_FIRMWARE);
+MODULE_FIRMWARE(XC5000C_FIRMWARE);
diff --git a/drivers/media/tuners/xc5000.h b/drivers/media/tuners/xc5000.h
new file mode 100644 (file)
index 0000000..b1a5474
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *  Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
+ *
+ *  Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
+ *
+ *  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 __XC5000_H__
+#define __XC5000_H__
+
+#include <linux/firmware.h>
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+#define XC5000A 1
+#define XC5000C 2
+
+struct xc5000_config {
+       u8   i2c_address;
+       u32  if_khz;
+       u8   radio_input;
+       u16  xtal_khz;
+
+       int chip_id;
+};
+
+/* xc5000 callback command */
+#define XC5000_TUNER_RESET             0
+
+/* Possible Radio inputs */
+#define XC5000_RADIO_NOT_CONFIGURED            0
+#define XC5000_RADIO_FM1                       1
+#define XC5000_RADIO_FM2                       2
+#define XC5000_RADIO_FM1_MONO                  3
+
+/* 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) || \
+    (defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE))
+extern struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
+                                         struct i2c_adapter *i2c,
+                                         const struct xc5000_config *cfg);
+#else
+static inline struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
+                                                struct i2c_adapter *i2c,
+                                                const struct xc5000_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif
+
+#endif
index 9eaf208bfa435ef0233b15be836f1f64be4e8043..2f7ee5cc5b296ac051e38ab12d0cda88fb2c7d7a 100644 (file)
@@ -3,5 +3,5 @@ obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o
 
 ccflags-y += -Idrivers/media/dvb-core/
 ccflags-y += -Idrivers/media/dvb-frontends/
-ccflags-y += -Idrivers/media/common/tuners/
+ccflags-y += -Idrivers/media/tuners/
 ccflags-y += -Idrivers/media/common/b2c2/
index 24248b3acd4f19bca198947ec9f020d8c04dd24f..62568430418b02269496372c7ff341e4f2b29792 100644 (file)
@@ -44,5 +44,5 @@ obj-$(CONFIG_DVB_USB_RTL28XXU) += dvb-usb-rtl28xxu.o
 
 ccflags-y += -I$(srctree)/drivers/media/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
-ccflags-y += -I$(srctree)/drivers/media/common/tuners
+ccflags-y += -I$(srctree)/drivers/media/tuners
 
index 94bdf4d51712257649f5ff1b5e866d77043a6fd3..d3ab1e74647d3d1402982661e9ae8af4d28d8464 100644 (file)
@@ -78,5 +78,5 @@ obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o
 ccflags-y += -I$(srctree)/drivers/media/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb-frontends/
 # due to tuner-xc3028
-ccflags-y += -I$(srctree)/drivers/media/common/tuners
+ccflags-y += -I$(srctree)/drivers/media/tuners
 ccflags-y += -I$(srctree)/drivers/media/pci/ttpci
index 74b65ea00f6371333857f75b52c61df3f499a120..c0e90bc23692ffda76caba72f1966261ae4bf375 100644 (file)
@@ -31,5 +31,5 @@ obj-$(CONFIG_VIDEOBUF2_DMA_SG) += videobuf2-dma-sg.o
 
 ccflags-y += -I$(srctree)/drivers/media/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
-ccflags-y += -I$(srctree)/drivers/media/common/tuners
+ccflags-y += -I$(srctree)/drivers/media/tuners
 
index 98160ce77d8d2311f098cf02ee6db316f411b1c7..9dff3e2ec61311f11d6310f78731b257a6459d0f 100644 (file)
@@ -192,4 +192,4 @@ obj-$(CONFIG_ARCH_OMAP)     += omap/
 
 ccflags-y += -I$(srctree)/drivers/media/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
-ccflags-y += -I$(srctree)/drivers/media/common/tuners
+ccflags-y += -I$(srctree)/drivers/media/tuners
index 61b69e68d950cc2b7a6ab504f60e7f1e8c7274ca..98cc20cc0ffb2538cd025899e51931f9535715c2 100644 (file)
@@ -2,7 +2,7 @@ au0828-objs     := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o au0828-vid
 
 obj-$(CONFIG_VIDEO_AU0828) += au0828.o
 
-ccflags-y += -Idrivers/media/common/tuners
+ccflags-y += -Idrivers/media/tuners
 ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
 
index 4cba4eff36d85858868dda5428f618f5fe3f86e8..f6351a25c267589f4cf237ce8b24d348be7c2b9c 100644 (file)
@@ -9,5 +9,5 @@ bttv-objs      :=      bttv-driver.o bttv-cards.o bttv-if.o \
 obj-$(CONFIG_VIDEO_BT848) += bttv.o
 
 ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
+ccflags-y += -Idrivers/media/tuners
 ccflags-y += -Idrivers/media/dvb-core
index db5ab12d84a3115212d664e6879d31a459d1da13..d3ff1545c2c5da5c05748e033abd9da64286ee38 100644 (file)
@@ -10,4 +10,4 @@ obj-$(CONFIG_VIDEO_CX18_ALSA) += cx18-alsa.o
 
 ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
-ccflags-y += -Idrivers/media/common/tuners
+ccflags-y += -Idrivers/media/tuners
index 9f2d4a9df3f2943cde77a8946b21c0ed9460356e..1d40fce7760105e09232f99c1c3898834d097108 100644 (file)
@@ -9,7 +9,7 @@ obj-$(CONFIG_VIDEO_CX231XX_ALSA) += cx231xx-alsa.o
 obj-$(CONFIG_VIDEO_CX231XX_DVB) += cx231xx-dvb.o
 
 ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
+ccflags-y += -Idrivers/media/tuners
 ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
 ccflags-y += -Idrivers/media/usb/dvb-usb
index 8f82e01a6675d87ac34c517e1cd9eeb389ab51f9..f92cc4c14f0c6d82a64cbdaa5135ab34ca0abbfd 100644 (file)
@@ -8,7 +8,7 @@ obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
 obj-$(CONFIG_MEDIA_ALTERA_CI) += altera-ci.o
 
 ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
+ccflags-y += -Idrivers/media/tuners
 ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
 
index af23e0c77e1636c8bf2c26a4730786899e10d432..1434e80948036b4c4c55bfda4c48665f1839697c 100644 (file)
@@ -8,6 +8,6 @@ obj-$(CONFIG_VIDEO_CX25821) += cx25821.o
 obj-$(CONFIG_VIDEO_CX25821_ALSA) += cx25821-alsa.o
 
 ccflags-y := -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
+ccflags-y += -Idrivers/media/tuners
 ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
index 5c4d3064d4947c848ba81d677fd1af4b264d73a3..884b4cdd8ff09fae05c772e49988ff6c313936ac 100644 (file)
@@ -11,6 +11,6 @@ obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
 obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o
 
 ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
+ccflags-y += -Idrivers/media/tuners
 ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
index f4118d23a70beb3b5ab65a431c333bfd9e7ffb1b..65c7c29e41612c860fdc3f87ccb8884bb4ad5297 100644 (file)
@@ -10,6 +10,6 @@ obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o
 obj-$(CONFIG_VIDEO_EM28XX_RC) += em28xx-rc.o
 
 ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
+ccflags-y += -Idrivers/media/tuners
 ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
index 0015bd46f6674c8e340e26ded7a7044b7959f4bc..80b4ec18475dce2aff8e7fb91af9424ae9936695 100644 (file)
@@ -8,7 +8,7 @@ obj-$(CONFIG_VIDEO_IVTV) += ivtv.o
 obj-$(CONFIG_VIDEO_FB_IVTV) += ivtvfb.o
 
 ccflags-y += -I$(srctree)/drivers/media/video
-ccflags-y += -I$(srctree)/drivers/media/common/tuners
+ccflags-y += -I$(srctree)/drivers/media/tuners
 ccflags-y += -I$(srctree)/drivers/media/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
 
index 1458797bafd209e4e8d0679a4a2c15e3bfa6f96f..bc716db797e33f4851462da10fe4f487a10a6c5e 100644 (file)
@@ -17,6 +17,6 @@ pvrusb2-objs  := pvrusb2-i2c-core.o \
 obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o
 
 ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
+ccflags-y += -Idrivers/media/tuners
 ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
index 7af78a868b1935bc04ee0b7596d84dc25d28fdf4..aba50088dcdc5a1d376c0df78b1353128d329d60 100644 (file)
@@ -11,6 +11,6 @@ obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o
 obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
 
 ccflags-y += -I$(srctree)/drivers/media/video
-ccflags-y += -I$(srctree)/drivers/media/common/tuners
+ccflags-y += -I$(srctree)/drivers/media/tuners
 ccflags-y += -I$(srctree)/drivers/media/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
index d8ed33d6b853c474d6554c997d23cfb97b36a012..847110c2e14c07315a2596238524ce12ac5daca8 100644 (file)
@@ -5,7 +5,7 @@ saa7164-objs    := saa7164-cards.o saa7164-core.o saa7164-i2c.o saa7164-dvb.o \
 obj-$(CONFIG_VIDEO_SAA7164) += saa7164.o
 
 ccflags-y += -I$(srctree)/drivers/media/video
-ccflags-y += -I$(srctree)/drivers/media/common/tuners
+ccflags-y += -I$(srctree)/drivers/media/tuners
 ccflags-y += -I$(srctree)/drivers/media/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
 
index 268d8251f0e974c59fe7ac237872cbffab7dd7b6..4d660879999f75d1afd07d3df4f0e45653071b5d 100644 (file)
@@ -3,7 +3,7 @@ poseidon-objs := pd-video.o pd-alsa.o pd-dvb.o pd-radio.o pd-main.o
 obj-$(CONFIG_VIDEO_TLG2300) += poseidon.o
 
 ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
+ccflags-y += -Idrivers/media/tuners
 ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
 
index 56cbcba778f633a9d7637849c999cdecde4ed88d..1feb8c9c816c523cabb5a75cdaaf39c93ae6e9ff 100644 (file)
@@ -10,6 +10,6 @@ obj-$(CONFIG_VIDEO_TM6000_ALSA) += tm6000-alsa.o
 obj-$(CONFIG_VIDEO_TM6000_DVB) += tm6000-dvb.o
 
 ccflags-y := -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
+ccflags-y += -Idrivers/media/tuners
 ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
index aea1e3b5f06b7c1b1b9c7687a3f0a52f02a29bf0..d55c6bd97a3557ba50e0995268965252ab6ed457 100644 (file)
@@ -3,4 +3,4 @@ usbvision-objs  := usbvision-core.o usbvision-video.o usbvision-i2c.o usbvision-
 obj-$(CONFIG_VIDEO_USBVISION) += usbvision.o
 
 ccflags-y += -Idrivers/media/video
-ccflags-y += -Idrivers/media/common/tuners
+ccflags-y += -Idrivers/media/tuners
index eb6bc595f1ac0785e513a434e3b6b4d4baf9da4b..b2905e65057c78179b3e6f68367614c8e81bb4e6 100644 (file)
@@ -2,4 +2,4 @@ obj-$(CONFIG_DVB_CXD2099) += cxd2099.o
 
 ccflags-y += -Idrivers/media/dvb-core/
 ccflags-y += -Idrivers/media/dvb-frontends/
-ccflags-y += -Idrivers/media/common/tuners/
+ccflags-y += -Idrivers/media/tuners/