Merge git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (70 commits)
V4L/DVB (7900): pvrusb: Fix Kconfig if DVB=m V4L_core=y
V4L/DVB (7899): Fixes a few remaining Kbuild issues at common/tuners
V4L/DVB (7898): Fix VIDEO_MEDIA Kconfig logic
V4L/DVB (7895): tveeprom: update Hauppauge analog audio and video decoders
V4L/DVB (7893): xc5000: bug-fix: allow multiple devices in a single system
V4L/DVB (7891): cx18/ivtv: fix open() kernel oops
V4L/DVB (7890): cx18: removed bogus and confusing conditional
V4L/DVB (7889): cx18: improve HVR-1600 detection.
V4L/DVB (7888): cx18: minor card definition updates.
V4L/DVB (7887): cx18: fix Compro H900 analog support.
V4L/DVB (7881): saa7134: fixed a compile warning in saa7134-core.c
V4L/DVB (7880): saa7134: remove explicit GPIO initialization
V4L/DVB(7879): Adding cx18 Support for mxl5005s
V4L/DVB(7878): mxl55005s: Makefile and Kconfig additions
V4L/DVB(7877): mxl5005s: Ensure debug is off
V4L/DVB(7876): mxl5005s: Remove incorrect copyright holders
V4L/DVB(7875): mxl5005s: Remove redundant functions
V4L/DVB(7874): mxl5005s: Fix function statics
V4L/DVB(7873): mxl5005s: Fix header includes.
V4L/DVB(7872): mxl5005s: checkpatch.pl compliance
...
diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
index 929b90c..191194e 100644
--- a/Documentation/video4linux/CARDLIST.cx23885
+++ b/Documentation/video4linux/CARDLIST.cx23885
@@ -5,6 +5,6 @@
4 -> DViCO FusionHDTV5 Express [18ac:d500]
5 -> Hauppauge WinTV-HVR1500Q [0070:7790,0070:7797]
6 -> Hauppauge WinTV-HVR1500 [0070:7710,0070:7717]
- 7 -> Hauppauge WinTV-HVR1200 [0070:71d1]
+ 7 -> Hauppauge WinTV-HVR1200 [0070:71d1,0070:71d3]
8 -> Hauppauge WinTV-HVR1700 [0070:8101]
9 -> Hauppauge WinTV-HVR1400 [0070:8010]
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index f40e092..1d6a245 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -14,4 +14,4 @@
13 -> Terratec Prodigy XS (em2880) [0ccd:0047]
14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
15 -> V-Gear PocketTV (em2800)
- 16 -> Hauppauge WinTV HVR 950 (em2880) [2040:6513]
+ 16 -> Hauppauge WinTV HVR 950 (em2880) [2040:6513,2040:6517,2040:651b,2040:651f]
diff --git a/MAINTAINERS b/MAINTAINERS
index b18242f..bc1c008 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1230,6 +1230,15 @@
M: jayakumar.alsa@gmail.com
S: Maintained
+CX18 VIDEO4LINUX DRIVER
+P: Hans Verkuil, Andy Walls
+M: hverkuil@xs4all.nl, awalls@radix.net
+L: ivtv-devel@ivtvdriver.org
+L: ivtv-users@ivtvdriver.org
+L: video4linux-list@redhat.com
+W: http://linuxtv.org
+S: Maintained
+
CYBERPRO FB DRIVER
P: Russell King
M: rmk@arm.linux.org.uk
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index ddf57e1..7a7803b 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -89,8 +89,7 @@
config VIDEO_MEDIA
tristate
- default DVB_CORE || VIDEO_DEV
- depends on DVB_CORE || VIDEO_DEV
+ default (DVB_CORE && (VIDEO_DEV = n)) || (VIDEO_DEV && (DVB_CORE = n)) || (DVB_CORE && VIDEO_DEV)
comment "Multimedia drivers"
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index 5be85ff..d620654 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -1,6 +1,6 @@
config MEDIA_ATTACH
bool "Load and attach frontend and tuner driver modules as needed"
- depends on DVB_CORE
+ depends on VIDEO_MEDIA
depends on MODULES
help
Remove the static dependency of DVB card drivers on all
@@ -19,10 +19,10 @@
config MEDIA_TUNER
tristate
- default DVB_CORE || VIDEO_DEV
- depends on DVB_CORE || VIDEO_DEV
- select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE
+ default VIDEO_MEDIA && I2C
+ depends on VIDEO_MEDIA && I2C
+ select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG
+ select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG
select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE
select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE
select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE
@@ -46,7 +46,7 @@
config MEDIA_TUNER_SIMPLE
tristate "Simple tuner support"
- depends on I2C
+ depends on VIDEO_MEDIA && I2C
select MEDIA_TUNER_TDA9887
default m if MEDIA_TUNER_CUSTOMIZE
help
@@ -54,7 +54,7 @@
config MEDIA_TUNER_TDA8290
tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo"
- depends on I2C
+ depends on VIDEO_MEDIA && I2C
select MEDIA_TUNER_TDA827X
select MEDIA_TUNER_TDA18271
default m if MEDIA_TUNER_CUSTOMIZE
@@ -63,21 +63,21 @@
config MEDIA_TUNER_TDA827X
tristate "Philips TDA827X silicon tuner"
- depends on DVB_CORE && I2C
+ depends on VIDEO_MEDIA && I2C
default m if DVB_FE_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 I2C
+ depends on VIDEO_MEDIA && I2C
default m if DVB_FE_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 I2C
+ depends on VIDEO_MEDIA && I2C
default m if MEDIA_TUNER_CUSTOMIZE
help
Say Y here to include support for Philips TDA9885/6/7
@@ -85,67 +85,79 @@
config MEDIA_TUNER_TEA5761
tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
- depends on I2C && EXPERIMENTAL
+ depends on VIDEO_MEDIA && I2C
+ depends on EXPERIMENTAL
default m if MEDIA_TUNER_CUSTOMIZE
help
Say Y here to include support for the Philips TEA5761 radio tuner.
config MEDIA_TUNER_TEA5767
tristate "TEA 5767 radio tuner"
- depends on I2C
+ depends on VIDEO_MEDIA && I2C
default m if MEDIA_TUNER_CUSTOMIZE
help
Say Y here to include support for the Philips TEA5767 radio tuner.
config MEDIA_TUNER_MT20XX
tristate "Microtune 2032 / 2050 tuners"
- depends on I2C
+ depends on VIDEO_MEDIA && I2C
default m if MEDIA_TUNER_CUSTOMIZE
help
Say Y here to include support for the MT2032 / MT2050 tuner.
config MEDIA_TUNER_MT2060
tristate "Microtune MT2060 silicon IF tuner"
- depends on I2C
+ depends on VIDEO_MEDIA && I2C
default m if DVB_FE_CUSTOMISE
help
A driver for the silicon IF tuner MT2060 from Microtune.
config MEDIA_TUNER_MT2266
tristate "Microtune MT2266 silicon tuner"
- depends on I2C
+ depends on VIDEO_MEDIA && I2C
default m if DVB_FE_CUSTOMISE
help
A driver for the silicon baseband tuner MT2266 from Microtune.
config MEDIA_TUNER_MT2131
tristate "Microtune MT2131 silicon tuner"
- depends on I2C
+ depends on VIDEO_MEDIA && I2C
default m if DVB_FE_CUSTOMISE
help
A driver for the silicon baseband tuner MT2131 from Microtune.
config MEDIA_TUNER_QT1010
tristate "Quantek QT1010 silicon tuner"
- depends on DVB_CORE && I2C
+ depends on VIDEO_MEDIA && I2C
default m if DVB_FE_CUSTOMISE
help
A driver for the silicon tuner QT1010 from Quantek.
config MEDIA_TUNER_XC2028
tristate "XCeive xc2028/xc3028 tuners"
- depends on I2C && FW_LOADER
+ depends on VIDEO_MEDIA && I2C
+ depends on HOTPLUG
+ select FW_LOADER
default m if MEDIA_TUNER_CUSTOMIZE
help
Say Y here to include support for the xc2028/xc3028 tuners.
config MEDIA_TUNER_XC5000
tristate "Xceive XC5000 silicon tuner"
- depends on I2C
+ depends on VIDEO_MEDIA && I2C
+ depends on HOTPLUG
+ select FW_LOADER
default m if DVB_FE_CUSTOMISE
help
A driver for the silicon tuner XC5000 from Xceive.
This device is only used inside a SiP called togther with a
demodulator for now.
+config MEDIA_TUNER_MXL5005S
+ tristate "MaxLinear MSL5005S silicon tuner"
+ depends on VIDEO_MEDIA && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A driver for the silicon tuner MXL5005S from MaxLinear.
+
endif # MEDIA_TUNER_CUSTOMIZE
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
index 236d9932..55f7e67 100644
--- a/drivers/media/common/tuners/Makefile
+++ b/drivers/media/common/tuners/Makefile
@@ -20,6 +20,7 @@
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
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c
new file mode 100644
index 0000000..5d05b53
--- /dev/null
+++ b/drivers/media/common/tuners/mxl5005s.c
@@ -0,0 +1,4110 @@
+/*
+ MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
+
+ Copyright (C) 2008 MaxLinear
+ Copyright (C) 2006 Steven Toth <stoth@hauppauge.com>
+ Functions:
+ mxl5005s_reset()
+ mxl5005s_writereg()
+ mxl5005s_writeregs()
+ mxl5005s_init()
+ mxl5005s_reconfigure()
+ mxl5005s_AssignTunerMode()
+ mxl5005s_set_params()
+ mxl5005s_get_frequency()
+ mxl5005s_get_bandwidth()
+ mxl5005s_release()
+ mxl5005s_attach()
+
+ Copyright (C) 2008 Realtek
+ Copyright (C) 2008 Jan Hoogenraad
+ Functions:
+ mxl5005s_SetRfFreqHz()
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+/*
+ History of this driver (Steven Toth):
+ I was given a public release of a linux driver that included
+ support for the MaxLinear MXL5005S silicon tuner. Analysis of
+ the tuner driver showed clearly three things.
+
+ 1. The tuner driver didn't support the LinuxTV tuner API
+ so the code Realtek added had to be removed.
+
+ 2. A significant amount of the driver is reference driver code
+ from MaxLinear, I felt it was important to identify and
+ preserve this.
+
+ 3. New code has to be added to interface correctly with the
+ LinuxTV API, as a regular kernel module.
+
+ Other than the reference driver enum's, I've clearly marked
+ sections of the code and retained the copyright of the
+ respective owners.
+*/
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include "dvb_frontend.h"
+#include "mxl5005s.h"
+
+static int debug;
+
+#define dprintk(level, arg...) do { \
+ if (level <= debug) \
+ printk(arg); \
+ } while (0)
+
+#define TUNER_REGS_NUM 104
+#define INITCTRL_NUM 40
+
+#ifdef _MXL_PRODUCTION
+#define CHCTRL_NUM 39
+#else
+#define CHCTRL_NUM 36
+#endif
+
+#define MXLCTRL_NUM 189
+#define MASTER_CONTROL_ADDR 9
+
+/* Enumeration of Master Control Register State */
+enum master_control_state {
+ MC_LOAD_START = 1,
+ MC_POWER_DOWN,
+ MC_SYNTH_RESET,
+ MC_SEQ_OFF
+};
+
+/* Enumeration of MXL5005 Tuner Modulation Type */
+enum {
+ MXL_DEFAULT_MODULATION = 0,
+ MXL_DVBT,
+ MXL_ATSC,
+ MXL_QAM,
+ MXL_ANALOG_CABLE,
+ MXL_ANALOG_OTA
+} tuner_modu_type;
+
+/* MXL5005 Tuner Register Struct */
+struct TunerReg {
+ u16 Reg_Num; /* Tuner Register Address */
+ u16 Reg_Val; /* Current sw programmed value waiting to be writen */
+};
+
+enum {
+ /* Initialization Control Names */
+ DN_IQTN_AMP_CUT = 1, /* 1 */
+ BB_MODE, /* 2 */
+ BB_BUF, /* 3 */
+ BB_BUF_OA, /* 4 */
+ BB_ALPF_BANDSELECT, /* 5 */
+ BB_IQSWAP, /* 6 */
+ BB_DLPF_BANDSEL, /* 7 */
+ RFSYN_CHP_GAIN, /* 8 */
+ RFSYN_EN_CHP_HIGAIN, /* 9 */
+ AGC_IF, /* 10 */
+ AGC_RF, /* 11 */
+ IF_DIVVAL, /* 12 */
+ IF_VCO_BIAS, /* 13 */
+ CHCAL_INT_MOD_IF, /* 14 */
+ CHCAL_FRAC_MOD_IF, /* 15 */
+ DRV_RES_SEL, /* 16 */
+ I_DRIVER, /* 17 */
+ EN_AAF, /* 18 */
+ EN_3P, /* 19 */
+ EN_AUX_3P, /* 20 */
+ SEL_AAF_BAND, /* 21 */
+ SEQ_ENCLK16_CLK_OUT, /* 22 */
+ SEQ_SEL4_16B, /* 23 */
+ XTAL_CAPSELECT, /* 24 */
+ IF_SEL_DBL, /* 25 */
+ RFSYN_R_DIV, /* 26 */
+ SEQ_EXTSYNTHCALIF, /* 27 */
+ SEQ_EXTDCCAL, /* 28 */
+ AGC_EN_RSSI, /* 29 */
+ RFA_ENCLKRFAGC, /* 30 */
+ RFA_RSSI_REFH, /* 31 */
+ RFA_RSSI_REF, /* 32 */
+ RFA_RSSI_REFL, /* 33 */
+ RFA_FLR, /* 34 */
+ RFA_CEIL, /* 35 */
+ SEQ_EXTIQFSMPULSE, /* 36 */
+ OVERRIDE_1, /* 37 */
+ BB_INITSTATE_DLPF_TUNE, /* 38 */
+ TG_R_DIV, /* 39 */
+ EN_CHP_LIN_B, /* 40 */
+
+ /* Channel Change Control Names */
+ DN_POLY = 51, /* 51 */
+ DN_RFGAIN, /* 52 */
+ DN_CAP_RFLPF, /* 53 */
+ DN_EN_VHFUHFBAR, /* 54 */
+ DN_GAIN_ADJUST, /* 55 */
+ DN_IQTNBUF_AMP, /* 56 */
+ DN_IQTNGNBFBIAS_BST, /* 57 */
+ RFSYN_EN_OUTMUX, /* 58 */
+ RFSYN_SEL_VCO_OUT, /* 59 */
+ RFSYN_SEL_VCO_HI, /* 60 */
+ RFSYN_SEL_DIVM, /* 61 */
+ RFSYN_RF_DIV_BIAS, /* 62 */
+ DN_SEL_FREQ, /* 63 */
+ RFSYN_VCO_BIAS, /* 64 */
+ CHCAL_INT_MOD_RF, /* 65 */
+ CHCAL_FRAC_MOD_RF, /* 66 */
+ RFSYN_LPF_R, /* 67 */
+ CHCAL_EN_INT_RF, /* 68 */
+ TG_LO_DIVVAL, /* 69 */
+ TG_LO_SELVAL, /* 70 */
+ TG_DIV_VAL, /* 71 */
+ TG_VCO_BIAS, /* 72 */
+ SEQ_EXTPOWERUP, /* 73 */
+ OVERRIDE_2, /* 74 */
+ OVERRIDE_3, /* 75 */
+ OVERRIDE_4, /* 76 */
+ SEQ_FSM_PULSE, /* 77 */
+ GPIO_4B, /* 78 */
+ GPIO_3B, /* 79 */
+ GPIO_4, /* 80 */
+ GPIO_3, /* 81 */
+ GPIO_1B, /* 82 */
+ DAC_A_ENABLE, /* 83 */
+ DAC_B_ENABLE, /* 84 */
+ DAC_DIN_A, /* 85 */
+ DAC_DIN_B, /* 86 */
+#ifdef _MXL_PRODUCTION
+ RFSYN_EN_DIV, /* 87 */
+ RFSYN_DIVM, /* 88 */
+ DN_BYPASS_AGC_I2C /* 89 */
+#endif
+} MXL5005_ControlName;
+
+/*
+ * The following context is source code provided by MaxLinear.
+ * MaxLinear source code - Common_MXL.h (?)
+ */
+
+/* Constants */
+#define MXL5005S_REG_WRITING_TABLE_LEN_MAX 104
+#define MXL5005S_LATCH_BYTE 0xfe
+
+/* Register address, MSB, and LSB */
+#define MXL5005S_BB_IQSWAP_ADDR 59
+#define MXL5005S_BB_IQSWAP_MSB 0
+#define MXL5005S_BB_IQSWAP_LSB 0
+
+#define MXL5005S_BB_DLPF_BANDSEL_ADDR 53
+#define MXL5005S_BB_DLPF_BANDSEL_MSB 4
+#define MXL5005S_BB_DLPF_BANDSEL_LSB 3
+
+/* Standard modes */
+enum {
+ MXL5005S_STANDARD_DVBT,
+ MXL5005S_STANDARD_ATSC,
+};
+#define MXL5005S_STANDARD_MODE_NUM 2
+
+/* Bandwidth modes */
+enum {
+ MXL5005S_BANDWIDTH_6MHZ = 6000000,
+ MXL5005S_BANDWIDTH_7MHZ = 7000000,
+ MXL5005S_BANDWIDTH_8MHZ = 8000000,
+};
+#define MXL5005S_BANDWIDTH_MODE_NUM 3
+
+/* MXL5005 Tuner Control Struct */
+struct TunerControl {
+ u16 Ctrl_Num; /* Control Number */
+ u16 size; /* Number of bits to represent Value */
+ u16 addr[25]; /* Array of Tuner Register Address for each bit pos */
+ u16 bit[25]; /* Array of bit pos in Reg Addr for each bit pos */
+ u16 val[25]; /* Binary representation of Value */
+};
+
+/* MXL5005 Tuner Struct */
+struct mxl5005s_state {
+ u8 Mode; /* 0: Analog Mode ; 1: Digital Mode */
+ u8 IF_Mode; /* for Analog Mode, 0: zero IF; 1: low IF */
+ u32 Chan_Bandwidth; /* filter channel bandwidth (6, 7, 8) */
+ u32 IF_OUT; /* Desired IF Out Frequency */
+ u16 IF_OUT_LOAD; /* IF Out Load Resistor (200/300 Ohms) */
+ u32 RF_IN; /* RF Input Frequency */
+ u32 Fxtal; /* XTAL Frequency */
+ u8 AGC_Mode; /* AGC Mode 0: Dual AGC; 1: Single AGC */
+ u16 TOP; /* Value: take over point */
+ u8 CLOCK_OUT; /* 0: turn off clk out; 1: turn on clock out */
+ u8 DIV_OUT; /* 4MHz or 16MHz */
+ u8 CAPSELECT; /* 0: disable On-Chip pulling cap; 1: enable */
+ u8 EN_RSSI; /* 0: disable RSSI; 1: enable RSSI */
+
+ /* Modulation Type; */
+ /* 0 - Default; 1 - DVB-T; 2 - ATSC; 3 - QAM; 4 - Analog Cable */
+ u8 Mod_Type;
+
+ /* Tracking Filter Type */
+ /* 0 - Default; 1 - Off; 2 - Type C; 3 - Type C-H */
+ u8 TF_Type;
+
+ /* Calculated Settings */
+ u32 RF_LO; /* Synth RF LO Frequency */
+ u32 IF_LO; /* Synth IF LO Frequency */
+ u32 TG_LO; /* Synth TG_LO Frequency */
+
+ /* Pointers to ControlName Arrays */
+ u16 Init_Ctrl_Num; /* Number of INIT Control Names */
+ struct TunerControl
+ Init_Ctrl[INITCTRL_NUM]; /* INIT Control Names Array Pointer */
+
+ u16 CH_Ctrl_Num; /* Number of CH Control Names */
+ struct TunerControl
+ CH_Ctrl[CHCTRL_NUM]; /* CH Control Name Array Pointer */
+
+ u16 MXL_Ctrl_Num; /* Number of MXL Control Names */
+ struct TunerControl
+ MXL_Ctrl[MXLCTRL_NUM]; /* MXL Control Name Array Pointer */
+
+ /* Pointer to Tuner Register Array */
+ u16 TunerRegs_Num; /* Number of Tuner Registers */
+ struct TunerReg
+ TunerRegs[TUNER_REGS_NUM]; /* Tuner Register Array Pointer */
+
+ /* Linux driver framework specific */
+ struct mxl5005s_config *config;
+ struct dvb_frontend *frontend;
+ struct i2c_adapter *i2c;
+
+ /* Cache values */
+ u32 current_mode;
+
+};
+
+static u16 MXL_GetMasterControl(u8 *MasterReg, int state);
+static u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value);
+static u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value);
+static void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit,
+ u8 bitVal);
+static u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 *RegNum,
+ u8 *RegVal, int *count);
+static u32 MXL_Ceiling(u32 value, u32 resolution);
+static u16 MXL_RegRead(struct dvb_frontend *fe, u8 RegNum, u8 *RegVal);
+static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum,
+ u32 value, u16 controlGroup);
+static u16 MXL_SetGPIO(struct dvb_frontend *fe, u8 GPIO_Num, u8 GPIO_Val);
+static u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 *RegNum,
+ u8 *RegVal, int *count);
+static u32 MXL_GetXtalInt(u32 Xtal_Freq);
+static u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq);
+static void MXL_SynthIFLO_Calc(struct dvb_frontend *fe);
+static void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe);
+static u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 *RegNum,
+ u8 *RegVal, int *count);
+static int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable,
+ u8 *datatable, u8 len);
+static u16 MXL_IFSynthInit(struct dvb_frontend *fe);
+static int mxl5005s_AssignTunerMode(struct dvb_frontend *fe, u32 mod_type,
+ u32 bandwidth);
+static int mxl5005s_reconfigure(struct dvb_frontend *fe, u32 mod_type,
+ u32 bandwidth);
+
+/* ----------------------------------------------------------------
+ * Begin: Custom code salvaged from the Realtek driver.
+ * Copyright (C) 2008 Realtek
+ * Copyright (C) 2008 Jan Hoogenraad
+ * This code is placed under the terms of the GNU General Public License
+ *
+ * Released by Realtek under GPLv2.
+ * Thanks to Realtek for a lot of support we received !
+ *
+ * Revision: 080314 - original version
+ */
+
+static int mxl5005s_SetRfFreqHz(struct dvb_frontend *fe, unsigned long RfFreqHz)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ unsigned char AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
+ unsigned char ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
+ int TableLen;
+
+ u32 IfDivval = 0;
+ unsigned char MasterControlByte;
+
+ dprintk(1, "%s() freq=%ld\n", __func__, RfFreqHz);
+
+ /* Set MxL5005S tuner RF frequency according to example code. */
+
+ /* Tuner RF frequency setting stage 0 */
+ MXL_GetMasterControl(ByteTable, MC_SYNTH_RESET);
+ AddrTable[0] = MASTER_CONTROL_ADDR;
+ ByteTable[0] |= state->config->AgcMasterByte;
+
+ mxl5005s_writeregs(fe, AddrTable, ByteTable, 1);
+
+ /* Tuner RF frequency setting stage 1 */
+ MXL_TuneRF(fe, RfFreqHz);
+
+ MXL_ControlRead(fe, IF_DIVVAL, &IfDivval);
+
+ MXL_ControlWrite(fe, SEQ_FSM_PULSE, 0);
+ MXL_ControlWrite(fe, SEQ_EXTPOWERUP, 1);
+ MXL_ControlWrite(fe, IF_DIVVAL, 8);
+ MXL_GetCHRegister(fe, AddrTable, ByteTable, &TableLen);
+
+ MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START);
+ AddrTable[TableLen] = MASTER_CONTROL_ADDR ;
+ ByteTable[TableLen] = MasterControlByte |
+ state->config->AgcMasterByte;
+ TableLen += 1;
+
+ mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen);
+
+ /* Wait 30 ms. */
+ msleep(150);
+
+ /* Tuner RF frequency setting stage 2 */
+ MXL_ControlWrite(fe, SEQ_FSM_PULSE, 1);
+ MXL_ControlWrite(fe, IF_DIVVAL, IfDivval);
+ MXL_GetCHRegister_ZeroIF(fe, AddrTable, ByteTable, &TableLen);
+
+ MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START);
+ AddrTable[TableLen] = MASTER_CONTROL_ADDR ;
+ ByteTable[TableLen] = MasterControlByte |
+ state->config->AgcMasterByte ;
+ TableLen += 1;
+
+ mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen);
+
+ msleep(100);
+
+ return 0;
+}
+/* End: Custom code taken from the Realtek driver */
+
+/* ----------------------------------------------------------------
+ * Begin: Reference driver code found in the Realtek driver.
+ * Copyright (C) 2008 MaxLinear
+ */
+static u16 MXL5005_RegisterInit(struct dvb_frontend *fe)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ state->TunerRegs_Num = TUNER_REGS_NUM ;
+
+ state->TunerRegs[0].Reg_Num = 9 ;
+ state->TunerRegs[0].Reg_Val = 0x40 ;
+
+ state->TunerRegs[1].Reg_Num = 11 ;
+ state->TunerRegs[1].Reg_Val = 0x19 ;
+
+ state->TunerRegs[2].Reg_Num = 12 ;
+ state->TunerRegs[2].Reg_Val = 0x60 ;
+
+ state->TunerRegs[3].Reg_Num = 13 ;
+ state->TunerRegs[3].Reg_Val = 0x00 ;
+
+ state->TunerRegs[4].Reg_Num = 14 ;
+ state->TunerRegs[4].Reg_Val = 0x00 ;
+
+ state->TunerRegs[5].Reg_Num = 15 ;
+ state->TunerRegs[5].Reg_Val = 0xC0 ;
+
+ state->TunerRegs[6].Reg_Num = 16 ;
+ state->TunerRegs[6].Reg_Val = 0x00 ;
+
+ state->TunerRegs[7].Reg_Num = 17 ;
+ state->TunerRegs[7].Reg_Val = 0x00 ;
+
+ state->TunerRegs[8].Reg_Num = 18 ;
+ state->TunerRegs[8].Reg_Val = 0x00 ;
+
+ state->TunerRegs[9].Reg_Num = 19 ;
+ state->TunerRegs[9].Reg_Val = 0x34 ;
+
+ state->TunerRegs[10].Reg_Num = 21 ;
+ state->TunerRegs[10].Reg_Val = 0x00 ;
+
+ state->TunerRegs[11].Reg_Num = 22 ;
+ state->TunerRegs[11].Reg_Val = 0x6B ;
+
+ state->TunerRegs[12].Reg_Num = 23 ;
+ state->TunerRegs[12].Reg_Val = 0x35 ;
+
+ state->TunerRegs[13].Reg_Num = 24 ;
+ state->TunerRegs[13].Reg_Val = 0x70 ;
+
+ state->TunerRegs[14].Reg_Num = 25 ;
+ state->TunerRegs[14].Reg_Val = 0x3E ;
+
+ state->TunerRegs[15].Reg_Num = 26 ;
+ state->TunerRegs[15].Reg_Val = 0x82 ;
+
+ state->TunerRegs[16].Reg_Num = 31 ;
+ state->TunerRegs[16].Reg_Val = 0x00 ;
+
+ state->TunerRegs[17].Reg_Num = 32 ;
+ state->TunerRegs[17].Reg_Val = 0x40 ;
+
+ state->TunerRegs[18].Reg_Num = 33 ;
+ state->TunerRegs[18].Reg_Val = 0x53 ;
+
+ state->TunerRegs[19].Reg_Num = 34 ;
+ state->TunerRegs[19].Reg_Val = 0x81 ;
+
+ state->TunerRegs[20].Reg_Num = 35 ;
+ state->TunerRegs[20].Reg_Val = 0xC9 ;
+
+ state->TunerRegs[21].Reg_Num = 36 ;
+ state->TunerRegs[21].Reg_Val = 0x01 ;
+
+ state->TunerRegs[22].Reg_Num = 37 ;
+ state->TunerRegs[22].Reg_Val = 0x00 ;
+
+ state->TunerRegs[23].Reg_Num = 41 ;
+ state->TunerRegs[23].Reg_Val = 0x00 ;
+
+ state->TunerRegs[24].Reg_Num = 42 ;
+ state->TunerRegs[24].Reg_Val = 0xF8 ;
+
+ state->TunerRegs[25].Reg_Num = 43 ;
+ state->TunerRegs[25].Reg_Val = 0x43 ;
+
+ state->TunerRegs[26].Reg_Num = 44 ;
+ state->TunerRegs[26].Reg_Val = 0x20 ;
+
+ state->TunerRegs[27].Reg_Num = 45 ;
+ state->TunerRegs[27].Reg_Val = 0x80 ;
+
+ state->TunerRegs[28].Reg_Num = 46 ;
+ state->TunerRegs[28].Reg_Val = 0x88 ;
+
+ state->TunerRegs[29].Reg_Num = 47 ;
+ state->TunerRegs[29].Reg_Val = 0x86 ;
+
+ state->TunerRegs[30].Reg_Num = 48 ;
+ state->TunerRegs[30].Reg_Val = 0x00 ;
+
+ state->TunerRegs[31].Reg_Num = 49 ;
+ state->TunerRegs[31].Reg_Val = 0x00 ;
+
+ state->TunerRegs[32].Reg_Num = 53 ;
+ state->TunerRegs[32].Reg_Val = 0x94 ;
+
+ state->TunerRegs[33].Reg_Num = 54 ;
+ state->TunerRegs[33].Reg_Val = 0xFA ;
+
+ state->TunerRegs[34].Reg_Num = 55 ;
+ state->TunerRegs[34].Reg_Val = 0x92 ;
+
+ state->TunerRegs[35].Reg_Num = 56 ;
+ state->TunerRegs[35].Reg_Val = 0x80 ;
+
+ state->TunerRegs[36].Reg_Num = 57 ;
+ state->TunerRegs[36].Reg_Val = 0x41 ;
+
+ state->TunerRegs[37].Reg_Num = 58 ;
+ state->TunerRegs[37].Reg_Val = 0xDB ;
+
+ state->TunerRegs[38].Reg_Num = 59 ;
+ state->TunerRegs[38].Reg_Val = 0x00 ;
+
+ state->TunerRegs[39].Reg_Num = 60 ;
+ state->TunerRegs[39].Reg_Val = 0x00 ;
+
+ state->TunerRegs[40].Reg_Num = 61 ;
+ state->TunerRegs[40].Reg_Val = 0x00 ;
+
+ state->TunerRegs[41].Reg_Num = 62 ;
+ state->TunerRegs[41].Reg_Val = 0x00 ;
+
+ state->TunerRegs[42].Reg_Num = 65 ;
+ state->TunerRegs[42].Reg_Val = 0xF8 ;
+
+ state->TunerRegs[43].Reg_Num = 66 ;
+ state->TunerRegs[43].Reg_Val = 0xE4 ;
+
+ state->TunerRegs[44].Reg_Num = 67 ;
+ state->TunerRegs[44].Reg_Val = 0x90 ;
+
+ state->TunerRegs[45].Reg_Num = 68 ;
+ state->TunerRegs[45].Reg_Val = 0xC0 ;
+
+ state->TunerRegs[46].Reg_Num = 69 ;
+ state->TunerRegs[46].Reg_Val = 0x01 ;
+
+ state->TunerRegs[47].Reg_Num = 70 ;
+ state->TunerRegs[47].Reg_Val = 0x50 ;
+
+ state->TunerRegs[48].Reg_Num = 71 ;
+ state->TunerRegs[48].Reg_Val = 0x06 ;
+
+ state->TunerRegs[49].Reg_Num = 72 ;
+ state->TunerRegs[49].Reg_Val = 0x00 ;
+
+ state->TunerRegs[50].Reg_Num = 73 ;
+ state->TunerRegs[50].Reg_Val = 0x20 ;
+
+ state->TunerRegs[51].Reg_Num = 76 ;
+ state->TunerRegs[51].Reg_Val = 0xBB ;
+
+ state->TunerRegs[52].Reg_Num = 77 ;
+ state->TunerRegs[52].Reg_Val = 0x13 ;
+
+ state->TunerRegs[53].Reg_Num = 81 ;
+ state->TunerRegs[53].Reg_Val = 0x04 ;
+
+ state->TunerRegs[54].Reg_Num = 82 ;
+ state->TunerRegs[54].Reg_Val = 0x75 ;
+
+ state->TunerRegs[55].Reg_Num = 83 ;
+ state->TunerRegs[55].Reg_Val = 0x00 ;
+
+ state->TunerRegs[56].Reg_Num = 84 ;
+ state->TunerRegs[56].Reg_Val = 0x00 ;
+
+ state->TunerRegs[57].Reg_Num = 85 ;
+ state->TunerRegs[57].Reg_Val = 0x00 ;
+
+ state->TunerRegs[58].Reg_Num = 91 ;
+ state->TunerRegs[58].Reg_Val = 0x70 ;
+
+ state->TunerRegs[59].Reg_Num = 92 ;
+ state->TunerRegs[59].Reg_Val = 0x00 ;
+
+ state->TunerRegs[60].Reg_Num = 93 ;
+ state->TunerRegs[60].Reg_Val = 0x00 ;
+
+ state->TunerRegs[61].Reg_Num = 94 ;
+ state->TunerRegs[61].Reg_Val = 0x00 ;
+
+ state->TunerRegs[62].Reg_Num = 95 ;
+ state->TunerRegs[62].Reg_Val = 0x0C ;
+
+ state->TunerRegs[63].Reg_Num = 96 ;
+ state->TunerRegs[63].Reg_Val = 0x00 ;
+
+ state->TunerRegs[64].Reg_Num = 97 ;
+ state->TunerRegs[64].Reg_Val = 0x00 ;
+
+ state->TunerRegs[65].Reg_Num = 98 ;
+ state->TunerRegs[65].Reg_Val = 0xE2 ;
+
+ state->TunerRegs[66].Reg_Num = 99 ;
+ state->TunerRegs[66].Reg_Val = 0x00 ;
+
+ state->TunerRegs[67].Reg_Num = 100 ;
+ state->TunerRegs[67].Reg_Val = 0x00 ;
+
+ state->TunerRegs[68].Reg_Num = 101 ;
+ state->TunerRegs[68].Reg_Val = 0x12 ;
+
+ state->TunerRegs[69].Reg_Num = 102 ;
+ state->TunerRegs[69].Reg_Val = 0x80 ;
+
+ state->TunerRegs[70].Reg_Num = 103 ;
+ state->TunerRegs[70].Reg_Val = 0x32 ;
+
+ state->TunerRegs[71].Reg_Num = 104 ;
+ state->TunerRegs[71].Reg_Val = 0xB4 ;
+
+ state->TunerRegs[72].Reg_Num = 105 ;
+ state->TunerRegs[72].Reg_Val = 0x60 ;
+
+ state->TunerRegs[73].Reg_Num = 106 ;
+ state->TunerRegs[73].Reg_Val = 0x83 ;
+
+ state->TunerRegs[74].Reg_Num = 107 ;
+ state->TunerRegs[74].Reg_Val = 0x84 ;
+
+ state->TunerRegs[75].Reg_Num = 108 ;
+ state->TunerRegs[75].Reg_Val = 0x9C ;
+
+ state->TunerRegs[76].Reg_Num = 109 ;
+ state->TunerRegs[76].Reg_Val = 0x02 ;
+
+ state->TunerRegs[77].Reg_Num = 110 ;
+ state->TunerRegs[77].Reg_Val = 0x81 ;
+
+ state->TunerRegs[78].Reg_Num = 111 ;
+ state->TunerRegs[78].Reg_Val = 0xC0 ;
+
+ state->TunerRegs[79].Reg_Num = 112 ;
+ state->TunerRegs[79].Reg_Val = 0x10 ;
+
+ state->TunerRegs[80].Reg_Num = 131 ;
+ state->TunerRegs[80].Reg_Val = 0x8A ;
+
+ state->TunerRegs[81].Reg_Num = 132 ;
+ state->TunerRegs[81].Reg_Val = 0x10 ;
+
+ state->TunerRegs[82].Reg_Num = 133 ;
+ state->TunerRegs[82].Reg_Val = 0x24 ;
+
+ state->TunerRegs[83].Reg_Num = 134 ;
+ state->TunerRegs[83].Reg_Val = 0x00 ;
+
+ state->TunerRegs[84].Reg_Num = 135 ;
+ state->TunerRegs[84].Reg_Val = 0x00 ;
+
+ state->TunerRegs[85].Reg_Num = 136 ;
+ state->TunerRegs[85].Reg_Val = 0x7E ;
+
+ state->TunerRegs[86].Reg_Num = 137 ;
+ state->TunerRegs[86].Reg_Val = 0x40 ;
+
+ state->TunerRegs[87].Reg_Num = 138 ;
+ state->TunerRegs[87].Reg_Val = 0x38 ;
+
+ state->TunerRegs[88].Reg_Num = 146 ;
+ state->TunerRegs[88].Reg_Val = 0xF6 ;
+
+ state->TunerRegs[89].Reg_Num = 147 ;
+ state->TunerRegs[89].Reg_Val = 0x1A ;
+
+ state->TunerRegs[90].Reg_Num = 148 ;
+ state->TunerRegs[90].Reg_Val = 0x62 ;
+
+ state->TunerRegs[91].Reg_Num = 149 ;
+ state->TunerRegs[91].Reg_Val = 0x33 ;
+
+ state->TunerRegs[92].Reg_Num = 150 ;
+ state->TunerRegs[92].Reg_Val = 0x80 ;
+
+ state->TunerRegs[93].Reg_Num = 156 ;
+ state->TunerRegs[93].Reg_Val = 0x56 ;
+
+ state->TunerRegs[94].Reg_Num = 157 ;
+ state->TunerRegs[94].Reg_Val = 0x17 ;
+
+ state->TunerRegs[95].Reg_Num = 158 ;
+ state->TunerRegs[95].Reg_Val = 0xA9 ;
+
+ state->TunerRegs[96].Reg_Num = 159 ;
+ state->TunerRegs[96].Reg_Val = 0x00 ;
+
+ state->TunerRegs[97].Reg_Num = 160 ;
+ state->TunerRegs[97].Reg_Val = 0x00 ;
+
+ state->TunerRegs[98].Reg_Num = 161 ;
+ state->TunerRegs[98].Reg_Val = 0x00 ;
+
+ state->TunerRegs[99].Reg_Num = 162 ;
+ state->TunerRegs[99].Reg_Val = 0x40 ;
+
+ state->TunerRegs[100].Reg_Num = 166 ;
+ state->TunerRegs[100].Reg_Val = 0xAE ;
+
+ state->TunerRegs[101].Reg_Num = 167 ;
+ state->TunerRegs[101].Reg_Val = 0x1B ;
+
+ state->TunerRegs[102].Reg_Num = 168 ;
+ state->TunerRegs[102].Reg_Val = 0xF2 ;
+
+ state->TunerRegs[103].Reg_Num = 195 ;
+ state->TunerRegs[103].Reg_Val = 0x00 ;
+
+ return 0 ;
+}
+
+static u16 MXL5005_ControlInit(struct dvb_frontend *fe)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ state->Init_Ctrl_Num = INITCTRL_NUM;
+
+ state->Init_Ctrl[0].Ctrl_Num = DN_IQTN_AMP_CUT ;
+ state->Init_Ctrl[0].size = 1 ;
+ state->Init_Ctrl[0].addr[0] = 73;
+ state->Init_Ctrl[0].bit[0] = 7;
+ state->Init_Ctrl[0].val[0] = 0;
+
+ state->Init_Ctrl[1].Ctrl_Num = BB_MODE ;
+ state->Init_Ctrl[1].size = 1 ;
+ state->Init_Ctrl[1].addr[0] = 53;
+ state->Init_Ctrl[1].bit[0] = 2;
+ state->Init_Ctrl[1].val[0] = 1;
+
+ state->Init_Ctrl[2].Ctrl_Num = BB_BUF ;
+ state->Init_Ctrl[2].size = 2 ;
+ state->Init_Ctrl[2].addr[0] = 53;
+ state->Init_Ctrl[2].bit[0] = 1;
+ state->Init_Ctrl[2].val[0] = 0;
+ state->Init_Ctrl[2].addr[1] = 57;
+ state->Init_Ctrl[2].bit[1] = 0;
+ state->Init_Ctrl[2].val[1] = 1;
+
+ state->Init_Ctrl[3].Ctrl_Num = BB_BUF_OA ;
+ state->Init_Ctrl[3].size = 1 ;
+ state->Init_Ctrl[3].addr[0] = 53;
+ state->Init_Ctrl[3].bit[0] = 0;
+ state->Init_Ctrl[3].val[0] = 0;
+
+ state->Init_Ctrl[4].Ctrl_Num = BB_ALPF_BANDSELECT ;
+ state->Init_Ctrl[4].size = 3 ;
+ state->Init_Ctrl[4].addr[0] = 53;
+ state->Init_Ctrl[4].bit[0] = 5;
+ state->Init_Ctrl[4].val[0] = 0;
+ state->Init_Ctrl[4].addr[1] = 53;
+ state->Init_Ctrl[4].bit[1] = 6;
+ state->Init_Ctrl[4].val[1] = 0;
+ state->Init_Ctrl[4].addr[2] = 53;
+ state->Init_Ctrl[4].bit[2] = 7;
+ state->Init_Ctrl[4].val[2] = 1;
+
+ state->Init_Ctrl[5].Ctrl_Num = BB_IQSWAP ;
+ state->Init_Ctrl[5].size = 1 ;
+ state->Init_Ctrl[5].addr[0] = 59;
+ state->Init_Ctrl[5].bit[0] = 0;
+ state->Init_Ctrl[5].val[0] = 0;
+
+ state->Init_Ctrl[6].Ctrl_Num = BB_DLPF_BANDSEL ;
+ state->Init_Ctrl[6].size = 2 ;
+ state->Init_Ctrl[6].addr[0] = 53;
+ state->Init_Ctrl[6].bit[0] = 3;
+ state->Init_Ctrl[6].val[0] = 0;
+ state->Init_Ctrl[6].addr[1] = 53;
+ state->Init_Ctrl[6].bit[1] = 4;
+ state->Init_Ctrl[6].val[1] = 1;
+
+ state->Init_Ctrl[7].Ctrl_Num = RFSYN_CHP_GAIN ;
+ state->Init_Ctrl[7].size = 4 ;
+ state->Init_Ctrl[7].addr[0] = 22;
+ state->Init_Ctrl[7].bit[0] = 4;
+ state->Init_Ctrl[7].val[0] = 0;
+ state->Init_Ctrl[7].addr[1] = 22;
+ state->Init_Ctrl[7].bit[1] = 5;
+ state->Init_Ctrl[7].val[1] = 1;
+ state->Init_Ctrl[7].addr[2] = 22;
+ state->Init_Ctrl[7].bit[2] = 6;
+ state->Init_Ctrl[7].val[2] = 1;
+ state->Init_Ctrl[7].addr[3] = 22;
+ state->Init_Ctrl[7].bit[3] = 7;
+ state->Init_Ctrl[7].val[3] = 0;
+
+ state->Init_Ctrl[8].Ctrl_Num = RFSYN_EN_CHP_HIGAIN ;
+ state->Init_Ctrl[8].size = 1 ;
+ state->Init_Ctrl[8].addr[0] = 22;
+ state->Init_Ctrl[8].bit[0] = 2;
+ state->Init_Ctrl[8].val[0] = 0;
+
+ state->Init_Ctrl[9].Ctrl_Num = AGC_IF ;
+ state->Init_Ctrl[9].size = 4 ;
+ state->Init_Ctrl[9].addr[0] = 76;
+ state->Init_Ctrl[9].bit[0] = 0;
+ state->Init_Ctrl[9].val[0] = 1;
+ state->Init_Ctrl[9].addr[1] = 76;
+ state->Init_Ctrl[9].bit[1] = 1;
+ state->Init_Ctrl[9].val[1] = 1;
+ state->Init_Ctrl[9].addr[2] = 76;
+ state->Init_Ctrl[9].bit[2] = 2;
+ state->Init_Ctrl[9].val[2] = 0;
+ state->Init_Ctrl[9].addr[3] = 76;
+ state->Init_Ctrl[9].bit[3] = 3;
+ state->Init_Ctrl[9].val[3] = 1;
+
+ state->Init_Ctrl[10].Ctrl_Num = AGC_RF ;
+ state->Init_Ctrl[10].size = 4 ;
+ state->Init_Ctrl[10].addr[0] = 76;
+ state->Init_Ctrl[10].bit[0] = 4;
+ state->Init_Ctrl[10].val[0] = 1;
+ state->Init_Ctrl[10].addr[1] = 76;
+ state->Init_Ctrl[10].bit[1] = 5;
+ state->Init_Ctrl[10].val[1] = 1;
+ state->Init_Ctrl[10].addr[2] = 76;
+ state->Init_Ctrl[10].bit[2] = 6;
+ state->Init_Ctrl[10].val[2] = 0;
+ state->Init_Ctrl[10].addr[3] = 76;
+ state->Init_Ctrl[10].bit[3] = 7;
+ state->Init_Ctrl[10].val[3] = 1;
+
+ state->Init_Ctrl[11].Ctrl_Num = IF_DIVVAL ;
+ state->Init_Ctrl[11].size = 5 ;
+ state->Init_Ctrl[11].addr[0] = 43;
+ state->Init_Ctrl[11].bit[0] = 3;
+ state->Init_Ctrl[11].val[0] = 0;
+ state->Init_Ctrl[11].addr[1] = 43;
+ state->Init_Ctrl[11].bit[1] = 4;
+ state->Init_Ctrl[11].val[1] = 0;
+ state->Init_Ctrl[11].addr[2] = 43;
+ state->Init_Ctrl[11].bit[2] = 5;
+ state->Init_Ctrl[11].val[2] = 0;
+ state->Init_Ctrl[11].addr[3] = 43;
+ state->Init_Ctrl[11].bit[3] = 6;
+ state->Init_Ctrl[11].val[3] = 1;
+ state->Init_Ctrl[11].addr[4] = 43;
+ state->Init_Ctrl[11].bit[4] = 7;
+ state->Init_Ctrl[11].val[4] = 0;
+
+ state->Init_Ctrl[12].Ctrl_Num = IF_VCO_BIAS ;
+ state->Init_Ctrl[12].size = 6 ;
+ state->Init_Ctrl[12].addr[0] = 44;
+ state->Init_Ctrl[12].bit[0] = 2;
+ state->Init_Ctrl[12].val[0] = 0;
+ state->Init_Ctrl[12].addr[1] = 44;
+ state->Init_Ctrl[12].bit[1] = 3;
+ state->Init_Ctrl[12].val[1] = 0;
+ state->Init_Ctrl[12].addr[2] = 44;
+ state->Init_Ctrl[12].bit[2] = 4;
+ state->Init_Ctrl[12].val[2] = 0;
+ state->Init_Ctrl[12].addr[3] = 44;
+ state->Init_Ctrl[12].bit[3] = 5;
+ state->Init_Ctrl[12].val[3] = 1;
+ state->Init_Ctrl[12].addr[4] = 44;
+ state->Init_Ctrl[12].bit[4] = 6;
+ state->Init_Ctrl[12].val[4] = 0;
+ state->Init_Ctrl[12].addr[5] = 44;
+ state->Init_Ctrl[12].bit[5] = 7;
+ state->Init_Ctrl[12].val[5] = 0;
+
+ state->Init_Ctrl[13].Ctrl_Num = CHCAL_INT_MOD_IF ;
+ state->Init_Ctrl[13].size = 7 ;
+ state->Init_Ctrl[13].addr[0] = 11;
+ state->Init_Ctrl[13].bit[0] = 0;
+ state->Init_Ctrl[13].val[0] = 1;
+ state->Init_Ctrl[13].addr[1] = 11;
+ state->Init_Ctrl[13].bit[1] = 1;
+ state->Init_Ctrl[13].val[1] = 0;
+ state->Init_Ctrl[13].addr[2] = 11;
+ state->Init_Ctrl[13].bit[2] = 2;
+ state->Init_Ctrl[13].val[2] = 0;
+ state->Init_Ctrl[13].addr[3] = 11;
+ state->Init_Ctrl[13].bit[3] = 3;
+ state->Init_Ctrl[13].val[3] = 1;
+ state->Init_Ctrl[13].addr[4] = 11;
+ state->Init_Ctrl[13].bit[4] = 4;
+ state->Init_Ctrl[13].val[4] = 1;
+ state->Init_Ctrl[13].addr[5] = 11;
+ state->Init_Ctrl[13].bit[5] = 5;
+ state->Init_Ctrl[13].val[5] = 0;
+ state->Init_Ctrl[13].addr[6] = 11;
+ state->Init_Ctrl[13].bit[6] = 6;
+ state->Init_Ctrl[13].val[6] = 0;
+
+ state->Init_Ctrl[14].Ctrl_Num = CHCAL_FRAC_MOD_IF ;
+ state->Init_Ctrl[14].size = 16 ;
+ state->Init_Ctrl[14].addr[0] = 13;
+ state->Init_Ctrl[14].bit[0] = 0;
+ state->Init_Ctrl[14].val[0] = 0;
+ state->Init_Ctrl[14].addr[1] = 13;
+ state->Init_Ctrl[14].bit[1] = 1;
+ state->Init_Ctrl[14].val[1] = 0;
+ state->Init_Ctrl[14].addr[2] = 13;
+ state->Init_Ctrl[14].bit[2] = 2;
+ state->Init_Ctrl[14].val[2] = 0;
+ state->Init_Ctrl[14].addr[3] = 13;
+ state->Init_Ctrl[14].bit[3] = 3;
+ state->Init_Ctrl[14].val[3] = 0;
+ state->Init_Ctrl[14].addr[4] = 13;
+ state->Init_Ctrl[14].bit[4] = 4;
+ state->Init_Ctrl[14].val[4] = 0;
+ state->Init_Ctrl[14].addr[5] = 13;
+ state->Init_Ctrl[14].bit[5] = 5;
+ state->Init_Ctrl[14].val[5] = 0;
+ state->Init_Ctrl[14].addr[6] = 13;
+ state->Init_Ctrl[14].bit[6] = 6;
+ state->Init_Ctrl[14].val[6] = 0;
+ state->Init_Ctrl[14].addr[7] = 13;
+ state->Init_Ctrl[14].bit[7] = 7;
+ state->Init_Ctrl[14].val[7] = 0;
+ state->Init_Ctrl[14].addr[8] = 12;
+ state->Init_Ctrl[14].bit[8] = 0;
+ state->Init_Ctrl[14].val[8] = 0;
+ state->Init_Ctrl[14].addr[9] = 12;
+ state->Init_Ctrl[14].bit[9] = 1;
+ state->Init_Ctrl[14].val[9] = 0;
+ state->Init_Ctrl[14].addr[10] = 12;
+ state->Init_Ctrl[14].bit[10] = 2;
+ state->Init_Ctrl[14].val[10] = 0;
+ state->Init_Ctrl[14].addr[11] = 12;
+ state->Init_Ctrl[14].bit[11] = 3;
+ state->Init_Ctrl[14].val[11] = 0;
+ state->Init_Ctrl[14].addr[12] = 12;
+ state->Init_Ctrl[14].bit[12] = 4;
+ state->Init_Ctrl[14].val[12] = 0;
+ state->Init_Ctrl[14].addr[13] = 12;
+ state->Init_Ctrl[14].bit[13] = 5;
+ state->Init_Ctrl[14].val[13] = 1;
+ state->Init_Ctrl[14].addr[14] = 12;
+ state->Init_Ctrl[14].bit[14] = 6;
+ state->Init_Ctrl[14].val[14] = 1;
+ state->Init_Ctrl[14].addr[15] = 12;
+ state->Init_Ctrl[14].bit[15] = 7;
+ state->Init_Ctrl[14].val[15] = 0;
+
+ state->Init_Ctrl[15].Ctrl_Num = DRV_RES_SEL ;
+ state->Init_Ctrl[15].size = 3 ;
+ state->Init_Ctrl[15].addr[0] = 147;
+ state->Init_Ctrl[15].bit[0] = 2;
+ state->Init_Ctrl[15].val[0] = 0;
+ state->Init_Ctrl[15].addr[1] = 147;
+ state->Init_Ctrl[15].bit[1] = 3;
+ state->Init_Ctrl[15].val[1] = 1;
+ state->Init_Ctrl[15].addr[2] = 147;
+ state->Init_Ctrl[15].bit[2] = 4;
+ state->Init_Ctrl[15].val[2] = 1;
+
+ state->Init_Ctrl[16].Ctrl_Num = I_DRIVER ;
+ state->Init_Ctrl[16].size = 2 ;
+ state->Init_Ctrl[16].addr[0] = 147;
+ state->Init_Ctrl[16].bit[0] = 0;
+ state->Init_Ctrl[16].val[0] = 0;
+ state->Init_Ctrl[16].addr[1] = 147;
+ state->Init_Ctrl[16].bit[1] = 1;
+ state->Init_Ctrl[16].val[1] = 1;
+
+ state->Init_Ctrl[17].Ctrl_Num = EN_AAF ;
+ state->Init_Ctrl[17].size = 1 ;
+ state->Init_Ctrl[17].addr[0] = 147;
+ state->Init_Ctrl[17].bit[0] = 7;
+ state->Init_Ctrl[17].val[0] = 0;
+
+ state->Init_Ctrl[18].Ctrl_Num = EN_3P ;
+ state->Init_Ctrl[18].size = 1 ;
+ state->Init_Ctrl[18].addr[0] = 147;
+ state->Init_Ctrl[18].bit[0] = 6;
+ state->Init_Ctrl[18].val[0] = 0;
+
+ state->Init_Ctrl[19].Ctrl_Num = EN_AUX_3P ;
+ state->Init_Ctrl[19].size = 1 ;
+ state->Init_Ctrl[19].addr[0] = 156;
+ state->Init_Ctrl[19].bit[0] = 0;
+ state->Init_Ctrl[19].val[0] = 0;
+
+ state->Init_Ctrl[20].Ctrl_Num = SEL_AAF_BAND ;
+ state->Init_Ctrl[20].size = 1 ;
+ state->Init_Ctrl[20].addr[0] = 147;
+ state->Init_Ctrl[20].bit[0] = 5;
+ state->Init_Ctrl[20].val[0] = 0;
+
+ state->Init_Ctrl[21].Ctrl_Num = SEQ_ENCLK16_CLK_OUT ;
+ state->Init_Ctrl[21].size = 1 ;
+ state->Init_Ctrl[21].addr[0] = 137;
+ state->Init_Ctrl[21].bit[0] = 4;
+ state->Init_Ctrl[21].val[0] = 0;
+
+ state->Init_Ctrl[22].Ctrl_Num = SEQ_SEL4_16B ;
+ state->Init_Ctrl[22].size = 1 ;
+ state->Init_Ctrl[22].addr[0] = 137;
+ state->Init_Ctrl[22].bit[0] = 7;
+ state->Init_Ctrl[22].val[0] = 0;
+
+ state->Init_Ctrl[23].Ctrl_Num = XTAL_CAPSELECT ;
+ state->Init_Ctrl[23].size = 1 ;
+ state->Init_Ctrl[23].addr[0] = 91;
+ state->Init_Ctrl[23].bit[0] = 5;
+ state->Init_Ctrl[23].val[0] = 1;
+
+ state->Init_Ctrl[24].Ctrl_Num = IF_SEL_DBL ;
+ state->Init_Ctrl[24].size = 1 ;
+ state->Init_Ctrl[24].addr[0] = 43;
+ state->Init_Ctrl[24].bit[0] = 0;
+ state->Init_Ctrl[24].val[0] = 1;
+
+ state->Init_Ctrl[25].Ctrl_Num = RFSYN_R_DIV ;
+ state->Init_Ctrl[25].size = 2 ;
+ state->Init_Ctrl[25].addr[0] = 22;
+ state->Init_Ctrl[25].bit[0] = 0;
+ state->Init_Ctrl[25].val[0] = 1;
+ state->Init_Ctrl[25].addr[1] = 22;
+ state->Init_Ctrl[25].bit[1] = 1;
+ state->Init_Ctrl[25].val[1] = 1;
+
+ state->Init_Ctrl[26].Ctrl_Num = SEQ_EXTSYNTHCALIF ;
+ state->Init_Ctrl[26].size = 1 ;
+ state->Init_Ctrl[26].addr[0] = 134;
+ state->Init_Ctrl[26].bit[0] = 2;
+ state->Init_Ctrl[26].val[0] = 0;
+
+ state->Init_Ctrl[27].Ctrl_Num = SEQ_EXTDCCAL ;
+ state->Init_Ctrl[27].size = 1 ;
+ state->Init_Ctrl[27].addr[0] = 137;
+ state->Init_Ctrl[27].bit[0] = 3;
+ state->Init_Ctrl[27].val[0] = 0;
+
+ state->Init_Ctrl[28].Ctrl_Num = AGC_EN_RSSI ;
+ state->Init_Ctrl[28].size = 1 ;
+ state->Init_Ctrl[28].addr[0] = 77;
+ state->Init_Ctrl[28].bit[0] = 7;
+ state->Init_Ctrl[28].val[0] = 0;
+
+ state->Init_Ctrl[29].Ctrl_Num = RFA_ENCLKRFAGC ;
+ state->Init_Ctrl[29].size = 1 ;
+ state->Init_Ctrl[29].addr[0] = 166;
+ state->Init_Ctrl[29].bit[0] = 7;
+ state->Init_Ctrl[29].val[0] = 1;
+
+ state->Init_Ctrl[30].Ctrl_Num = RFA_RSSI_REFH ;
+ state->Init_Ctrl[30].size = 3 ;
+ state->Init_Ctrl[30].addr[0] = 166;
+ state->Init_Ctrl[30].bit[0] = 0;
+ state->Init_Ctrl[30].val[0] = 0;
+ state->Init_Ctrl[30].addr[1] = 166;
+ state->Init_Ctrl[30].bit[1] = 1;
+ state->Init_Ctrl[30].val[1] = 1;
+ state->Init_Ctrl[30].addr[2] = 166;
+ state->Init_Ctrl[30].bit[2] = 2;
+ state->Init_Ctrl[30].val[2] = 1;
+
+ state->Init_Ctrl[31].Ctrl_Num = RFA_RSSI_REF ;
+ state->Init_Ctrl[31].size = 3 ;
+ state->Init_Ctrl[31].addr[0] = 166;
+ state->Init_Ctrl[31].bit[0] = 3;
+ state->Init_Ctrl[31].val[0] = 1;
+ state->Init_Ctrl[31].addr[1] = 166;
+ state->Init_Ctrl[31].bit[1] = 4;
+ state->Init_Ctrl[31].val[1] = 0;
+ state->Init_Ctrl[31].addr[2] = 166;
+ state->Init_Ctrl[31].bit[2] = 5;
+ state->Init_Ctrl[31].val[2] = 1;
+
+ state->Init_Ctrl[32].Ctrl_Num = RFA_RSSI_REFL ;
+ state->Init_Ctrl[32].size = 3 ;
+ state->Init_Ctrl[32].addr[0] = 167;
+ state->Init_Ctrl[32].bit[0] = 0;
+ state->Init_Ctrl[32].val[0] = 1;
+ state->Init_Ctrl[32].addr[1] = 167;
+ state->Init_Ctrl[32].bit[1] = 1;
+ state->Init_Ctrl[32].val[1] = 1;
+ state->Init_Ctrl[32].addr[2] = 167;
+ state->Init_Ctrl[32].bit[2] = 2;
+ state->Init_Ctrl[32].val[2] = 0;
+
+ state->Init_Ctrl[33].Ctrl_Num = RFA_FLR ;
+ state->Init_Ctrl[33].size = 4 ;
+ state->Init_Ctrl[33].addr[0] = 168;
+ state->Init_Ctrl[33].bit[0] = 0;
+ state->Init_Ctrl[33].val[0] = 0;
+ state->Init_Ctrl[33].addr[1] = 168;
+ state->Init_Ctrl[33].bit[1] = 1;
+ state->Init_Ctrl[33].val[1] = 1;
+ state->Init_Ctrl[33].addr[2] = 168;
+ state->Init_Ctrl[33].bit[2] = 2;
+ state->Init_Ctrl[33].val[2] = 0;
+ state->Init_Ctrl[33].addr[3] = 168;
+ state->Init_Ctrl[33].bit[3] = 3;
+ state->Init_Ctrl[33].val[3] = 0;
+
+ state->Init_Ctrl[34].Ctrl_Num = RFA_CEIL ;
+ state->Init_Ctrl[34].size = 4 ;
+ state->Init_Ctrl[34].addr[0] = 168;
+ state->Init_Ctrl[34].bit[0] = 4;
+ state->Init_Ctrl[34].val[0] = 1;
+ state->Init_Ctrl[34].addr[1] = 168;
+ state->Init_Ctrl[34].bit[1] = 5;
+ state->Init_Ctrl[34].val[1] = 1;
+ state->Init_Ctrl[34].addr[2] = 168;
+ state->Init_Ctrl[34].bit[2] = 6;
+ state->Init_Ctrl[34].val[2] = 1;
+ state->Init_Ctrl[34].addr[3] = 168;
+ state->Init_Ctrl[34].bit[3] = 7;
+ state->Init_Ctrl[34].val[3] = 1;
+
+ state->Init_Ctrl[35].Ctrl_Num = SEQ_EXTIQFSMPULSE ;
+ state->Init_Ctrl[35].size = 1 ;
+ state->Init_Ctrl[35].addr[0] = 135;
+ state->Init_Ctrl[35].bit[0] = 0;
+ state->Init_Ctrl[35].val[0] = 0;
+
+ state->Init_Ctrl[36].Ctrl_Num = OVERRIDE_1 ;
+ state->Init_Ctrl[36].size = 1 ;
+ state->Init_Ctrl[36].addr[0] = 56;
+ state->Init_Ctrl[36].bit[0] = 3;
+ state->Init_Ctrl[36].val[0] = 0;
+
+ state->Init_Ctrl[37].Ctrl_Num = BB_INITSTATE_DLPF_TUNE ;
+ state->Init_Ctrl[37].size = 7 ;
+ state->Init_Ctrl[37].addr[0] = 59;
+ state->Init_Ctrl[37].bit[0] = 1;
+ state->Init_Ctrl[37].val[0] = 0;
+ state->Init_Ctrl[37].addr[1] = 59;
+ state->Init_Ctrl[37].bit[1] = 2;
+ state->Init_Ctrl[37].val[1] = 0;
+ state->Init_Ctrl[37].addr[2] = 59;
+ state->Init_Ctrl[37].bit[2] = 3;
+ state->Init_Ctrl[37].val[2] = 0;
+ state->Init_Ctrl[37].addr[3] = 59;
+ state->Init_Ctrl[37].bit[3] = 4;
+ state->Init_Ctrl[37].val[3] = 0;
+ state->Init_Ctrl[37].addr[4] = 59;
+ state->Init_Ctrl[37].bit[4] = 5;
+ state->Init_Ctrl[37].val[4] = 0;
+ state->Init_Ctrl[37].addr[5] = 59;
+ state->Init_Ctrl[37].bit[5] = 6;
+ state->Init_Ctrl[37].val[5] = 0;
+ state->Init_Ctrl[37].addr[6] = 59;
+ state->Init_Ctrl[37].bit[6] = 7;
+ state->Init_Ctrl[37].val[6] = 0;
+
+ state->Init_Ctrl[38].Ctrl_Num = TG_R_DIV ;
+ state->Init_Ctrl[38].size = 6 ;
+ state->Init_Ctrl[38].addr[0] = 32;
+ state->Init_Ctrl[38].bit[0] = 2;
+ state->Init_Ctrl[38].val[0] = 0;
+ state->Init_Ctrl[38].addr[1] = 32;
+ state->Init_Ctrl[38].bit[1] = 3;
+ state->Init_Ctrl[38].val[1] = 0;
+ state->Init_Ctrl[38].addr[2] = 32;
+ state->Init_Ctrl[38].bit[2] = 4;
+ state->Init_Ctrl[38].val[2] = 0;
+ state->Init_Ctrl[38].addr[3] = 32;
+ state->Init_Ctrl[38].bit[3] = 5;
+ state->Init_Ctrl[38].val[3] = 0;
+ state->Init_Ctrl[38].addr[4] = 32;
+ state->Init_Ctrl[38].bit[4] = 6;
+ state->Init_Ctrl[38].val[4] = 1;
+ state->Init_Ctrl[38].addr[5] = 32;
+ state->Init_Ctrl[38].bit[5] = 7;
+ state->Init_Ctrl[38].val[5] = 0;
+
+ state->Init_Ctrl[39].Ctrl_Num = EN_CHP_LIN_B ;
+ state->Init_Ctrl[39].size = 1 ;
+ state->Init_Ctrl[39].addr[0] = 25;
+ state->Init_Ctrl[39].bit[0] = 3;
+ state->Init_Ctrl[39].val[0] = 1;
+
+
+ state->CH_Ctrl_Num = CHCTRL_NUM ;
+
+ state->CH_Ctrl[0].Ctrl_Num = DN_POLY ;
+ state->CH_Ctrl[0].size = 2 ;
+ state->CH_Ctrl[0].addr[0] = 68;
+ state->CH_Ctrl[0].bit[0] = 6;
+ state->CH_Ctrl[0].val[0] = 1;
+ state->CH_Ctrl[0].addr[1] = 68;
+ state->CH_Ctrl[0].bit[1] = 7;
+ state->CH_Ctrl[0].val[1] = 1;
+
+ state->CH_Ctrl[1].Ctrl_Num = DN_RFGAIN ;
+ state->CH_Ctrl[1].size = 2 ;
+ state->CH_Ctrl[1].addr[0] = 70;
+ state->CH_Ctrl[1].bit[0] = 6;
+ state->CH_Ctrl[1].val[0] = 1;
+ state->CH_Ctrl[1].addr[1] = 70;
+ state->CH_Ctrl[1].bit[1] = 7;
+ state->CH_Ctrl[1].val[1] = 0;
+
+ state->CH_Ctrl[2].Ctrl_Num = DN_CAP_RFLPF ;
+ state->CH_Ctrl[2].size = 9 ;
+ state->CH_Ctrl[2].addr[0] = 69;
+ state->CH_Ctrl[2].bit[0] = 5;
+ state->CH_Ctrl[2].val[0] = 0;
+ state->CH_Ctrl[2].addr[1] = 69;
+ state->CH_Ctrl[2].bit[1] = 6;
+ state->CH_Ctrl[2].val[1] = 0;
+ state->CH_Ctrl[2].addr[2] = 69;
+ state->CH_Ctrl[2].bit[2] = 7;
+ state->CH_Ctrl[2].val[2] = 0;
+ state->CH_Ctrl[2].addr[3] = 68;
+ state->CH_Ctrl[2].bit[3] = 0;
+ state->CH_Ctrl[2].val[3] = 0;
+ state->CH_Ctrl[2].addr[4] = 68;
+ state->CH_Ctrl[2].bit[4] = 1;
+ state->CH_Ctrl[2].val[4] = 0;
+ state->CH_Ctrl[2].addr[5] = 68;
+ state->CH_Ctrl[2].bit[5] = 2;
+ state->CH_Ctrl[2].val[5] = 0;
+ state->CH_Ctrl[2].addr[6] = 68;
+ state->CH_Ctrl[2].bit[6] = 3;
+ state->CH_Ctrl[2].val[6] = 0;
+ state->CH_Ctrl[2].addr[7] = 68;
+ state->CH_Ctrl[2].bit[7] = 4;
+ state->CH_Ctrl[2].val[7] = 0;
+ state->CH_Ctrl[2].addr[8] = 68;
+ state->CH_Ctrl[2].bit[8] = 5;
+ state->CH_Ctrl[2].val[8] = 0;
+
+ state->CH_Ctrl[3].Ctrl_Num = DN_EN_VHFUHFBAR ;
+ state->CH_Ctrl[3].size = 1 ;
+ state->CH_Ctrl[3].addr[0] = 70;
+ state->CH_Ctrl[3].bit[0] = 5;
+ state->CH_Ctrl[3].val[0] = 0;
+
+ state->CH_Ctrl[4].Ctrl_Num = DN_GAIN_ADJUST ;
+ state->CH_Ctrl[4].size = 3 ;
+ state->CH_Ctrl[4].addr[0] = 73;
+ state->CH_Ctrl[4].bit[0] = 4;
+ state->CH_Ctrl[4].val[0] = 0;
+ state->CH_Ctrl[4].addr[1] = 73;
+ state->CH_Ctrl[4].bit[1] = 5;
+ state->CH_Ctrl[4].val[1] = 1;
+ state->CH_Ctrl[4].addr[2] = 73;
+ state->CH_Ctrl[4].bit[2] = 6;
+ state->CH_Ctrl[4].val[2] = 0;
+
+ state->CH_Ctrl[5].Ctrl_Num = DN_IQTNBUF_AMP ;
+ state->CH_Ctrl[5].size = 4 ;
+ state->CH_Ctrl[5].addr[0] = 70;
+ state->CH_Ctrl[5].bit[0] = 0;
+ state->CH_Ctrl[5].val[0] = 0;
+ state->CH_Ctrl[5].addr[1] = 70;
+ state->CH_Ctrl[5].bit[1] = 1;
+ state->CH_Ctrl[5].val[1] = 0;
+ state->CH_Ctrl[5].addr[2] = 70;
+ state->CH_Ctrl[5].bit[2] = 2;
+ state->CH_Ctrl[5].val[2] = 0;
+ state->CH_Ctrl[5].addr[3] = 70;
+ state->CH_Ctrl[5].bit[3] = 3;
+ state->CH_Ctrl[5].val[3] = 0;
+
+ state->CH_Ctrl[6].Ctrl_Num = DN_IQTNGNBFBIAS_BST ;
+ state->CH_Ctrl[6].size = 1 ;
+ state->CH_Ctrl[6].addr[0] = 70;
+ state->CH_Ctrl[6].bit[0] = 4;
+ state->CH_Ctrl[6].val[0] = 1;
+
+ state->CH_Ctrl[7].Ctrl_Num = RFSYN_EN_OUTMUX ;
+ state->CH_Ctrl[7].size = 1 ;
+ state->CH_Ctrl[7].addr[0] = 111;
+ state->CH_Ctrl[7].bit[0] = 4;
+ state->CH_Ctrl[7].val[0] = 0;
+
+ state->CH_Ctrl[8].Ctrl_Num = RFSYN_SEL_VCO_OUT ;
+ state->CH_Ctrl[8].size = 1 ;
+ state->CH_Ctrl[8].addr[0] = 111;
+ state->CH_Ctrl[8].bit[0] = 7;
+ state->CH_Ctrl[8].val[0] = 1;
+
+ state->CH_Ctrl[9].Ctrl_Num = RFSYN_SEL_VCO_HI ;
+ state->CH_Ctrl[9].size = 1 ;
+ state->CH_Ctrl[9].addr[0] = 111;
+ state->CH_Ctrl[9].bit[0] = 6;
+ state->CH_Ctrl[9].val[0] = 1;
+
+ state->CH_Ctrl[10].Ctrl_Num = RFSYN_SEL_DIVM ;
+ state->CH_Ctrl[10].size = 1 ;
+ state->CH_Ctrl[10].addr[0] = 111;
+ state->CH_Ctrl[10].bit[0] = 5;
+ state->CH_Ctrl[10].val[0] = 0;
+
+ state->CH_Ctrl[11].Ctrl_Num = RFSYN_RF_DIV_BIAS ;
+ state->CH_Ctrl[11].size = 2 ;
+ state->CH_Ctrl[11].addr[0] = 110;
+ state->CH_Ctrl[11].bit[0] = 0;
+ state->CH_Ctrl[11].val[0] = 1;
+ state->CH_Ctrl[11].addr[1] = 110;
+ state->CH_Ctrl[11].bit[1] = 1;
+ state->CH_Ctrl[11].val[1] = 0;
+
+ state->CH_Ctrl[12].Ctrl_Num = DN_SEL_FREQ ;
+ state->CH_Ctrl[12].size = 3 ;
+ state->CH_Ctrl[12].addr[0] = 69;
+ state->CH_Ctrl[12].bit[0] = 2;
+ state->CH_Ctrl[12].val[0] = 0;
+ state->CH_Ctrl[12].addr[1] = 69;
+ state->CH_Ctrl[12].bit[1] = 3;
+ state->CH_Ctrl[12].val[1] = 0;
+ state->CH_Ctrl[12].addr[2] = 69;
+ state->CH_Ctrl[12].bit[2] = 4;
+ state->CH_Ctrl[12].val[2] = 0;
+
+ state->CH_Ctrl[13].Ctrl_Num = RFSYN_VCO_BIAS ;
+ state->CH_Ctrl[13].size = 6 ;
+ state->CH_Ctrl[13].addr[0] = 110;
+ state->CH_Ctrl[13].bit[0] = 2;
+ state->CH_Ctrl[13].val[0] = 0;
+ state->CH_Ctrl[13].addr[1] = 110;
+ state->CH_Ctrl[13].bit[1] = 3;
+ state->CH_Ctrl[13].val[1] = 0;
+ state->CH_Ctrl[13].addr[2] = 110;
+ state->CH_Ctrl[13].bit[2] = 4;
+ state->CH_Ctrl[13].val[2] = 0;
+ state->CH_Ctrl[13].addr[3] = 110;
+ state->CH_Ctrl[13].bit[3] = 5;
+ state->CH_Ctrl[13].val[3] = 0;
+ state->CH_Ctrl[13].addr[4] = 110;
+ state->CH_Ctrl[13].bit[4] = 6;
+ state->CH_Ctrl[13].val[4] = 0;
+ state->CH_Ctrl[13].addr[5] = 110;
+ state->CH_Ctrl[13].bit[5] = 7;
+ state->CH_Ctrl[13].val[5] = 1;
+
+ state->CH_Ctrl[14].Ctrl_Num = CHCAL_INT_MOD_RF ;
+ state->CH_Ctrl[14].size = 7 ;
+ state->CH_Ctrl[14].addr[0] = 14;
+ state->CH_Ctrl[14].bit[0] = 0;
+ state->CH_Ctrl[14].val[0] = 0;
+ state->CH_Ctrl[14].addr[1] = 14;
+ state->CH_Ctrl[14].bit[1] = 1;
+ state->CH_Ctrl[14].val[1] = 0;
+ state->CH_Ctrl[14].addr[2] = 14;
+ state->CH_Ctrl[14].bit[2] = 2;
+ state->CH_Ctrl[14].val[2] = 0;
+ state->CH_Ctrl[14].addr[3] = 14;
+ state->CH_Ctrl[14].bit[3] = 3;
+ state->CH_Ctrl[14].val[3] = 0;
+ state->CH_Ctrl[14].addr[4] = 14;
+ state->CH_Ctrl[14].bit[4] = 4;
+ state->CH_Ctrl[14].val[4] = 0;
+ state->CH_Ctrl[14].addr[5] = 14;
+ state->CH_Ctrl[14].bit[5] = 5;
+ state->CH_Ctrl[14].val[5] = 0;
+ state->CH_Ctrl[14].addr[6] = 14;
+ state->CH_Ctrl[14].bit[6] = 6;
+ state->CH_Ctrl[14].val[6] = 0;
+
+ state->CH_Ctrl[15].Ctrl_Num = CHCAL_FRAC_MOD_RF ;
+ state->CH_Ctrl[15].size = 18 ;
+ state->CH_Ctrl[15].addr[0] = 17;
+ state->CH_Ctrl[15].bit[0] = 6;
+ state->CH_Ctrl[15].val[0] = 0;
+ state->CH_Ctrl[15].addr[1] = 17;
+ state->CH_Ctrl[15].bit[1] = 7;
+ state->CH_Ctrl[15].val[1] = 0;
+ state->CH_Ctrl[15].addr[2] = 16;
+ state->CH_Ctrl[15].bit[2] = 0;
+ state->CH_Ctrl[15].val[2] = 0;
+ state->CH_Ctrl[15].addr[3] = 16;
+ state->CH_Ctrl[15].bit[3] = 1;
+ state->CH_Ctrl[15].val[3] = 0;
+ state->CH_Ctrl[15].addr[4] = 16;
+ state->CH_Ctrl[15].bit[4] = 2;
+ state->CH_Ctrl[15].val[4] = 0;
+ state->CH_Ctrl[15].addr[5] = 16;
+ state->CH_Ctrl[15].bit[5] = 3;
+ state->CH_Ctrl[15].val[5] = 0;
+ state->CH_Ctrl[15].addr[6] = 16;
+ state->CH_Ctrl[15].bit[6] = 4;
+ state->CH_Ctrl[15].val[6] = 0;
+ state->CH_Ctrl[15].addr[7] = 16;
+ state->CH_Ctrl[15].bit[7] = 5;
+ state->CH_Ctrl[15].val[7] = 0;
+ state->CH_Ctrl[15].addr[8] = 16;
+ state->CH_Ctrl[15].bit[8] = 6;
+ state->CH_Ctrl[15].val[8] = 0;
+ state->CH_Ctrl[15].addr[9] = 16;
+ state->CH_Ctrl[15].bit[9] = 7;
+ state->CH_Ctrl[15].val[9] = 0;
+ state->CH_Ctrl[15].addr[10] = 15;
+ state->CH_Ctrl[15].bit[10] = 0;
+ state->CH_Ctrl[15].val[10] = 0;
+ state->CH_Ctrl[15].addr[11] = 15;
+ state->CH_Ctrl[15].bit[11] = 1;
+ state->CH_Ctrl[15].val[11] = 0;
+ state->CH_Ctrl[15].addr[12] = 15;
+ state->CH_Ctrl[15].bit[12] = 2;
+ state->CH_Ctrl[15].val[12] = 0;
+ state->CH_Ctrl[15].addr[13] = 15;
+ state->CH_Ctrl[15].bit[13] = 3;
+ state->CH_Ctrl[15].val[13] = 0;
+ state->CH_Ctrl[15].addr[14] = 15;
+ state->CH_Ctrl[15].bit[14] = 4;
+ state->CH_Ctrl[15].val[14] = 0;
+ state->CH_Ctrl[15].addr[15] = 15;
+ state->CH_Ctrl[15].bit[15] = 5;
+ state->CH_Ctrl[15].val[15] = 0;
+ state->CH_Ctrl[15].addr[16] = 15;
+ state->CH_Ctrl[15].bit[16] = 6;
+ state->CH_Ctrl[15].val[16] = 1;
+ state->CH_Ctrl[15].addr[17] = 15;
+ state->CH_Ctrl[15].bit[17] = 7;
+ state->CH_Ctrl[15].val[17] = 1;
+
+ state->CH_Ctrl[16].Ctrl_Num = RFSYN_LPF_R ;
+ state->CH_Ctrl[16].size = 5 ;
+ state->CH_Ctrl[16].addr[0] = 112;
+ state->CH_Ctrl[16].bit[0] = 0;
+ state->CH_Ctrl[16].val[0] = 0;
+ state->CH_Ctrl[16].addr[1] = 112;
+ state->CH_Ctrl[16].bit[1] = 1;
+ state->CH_Ctrl[16].val[1] = 0;
+ state->CH_Ctrl[16].addr[2] = 112;
+ state->CH_Ctrl[16].bit[2] = 2;
+ state->CH_Ctrl[16].val[2] = 0;
+ state->CH_Ctrl[16].addr[3] = 112;
+ state->CH_Ctrl[16].bit[3] = 3;
+ state->CH_Ctrl[16].val[3] = 0;
+ state->CH_Ctrl[16].addr[4] = 112;
+ state->CH_Ctrl[16].bit[4] = 4;
+ state->CH_Ctrl[16].val[4] = 1;
+
+ state->CH_Ctrl[17].Ctrl_Num = CHCAL_EN_INT_RF ;
+ state->CH_Ctrl[17].size = 1 ;
+ state->CH_Ctrl[17].addr[0] = 14;
+ state->CH_Ctrl[17].bit[0] = 7;
+ state->CH_Ctrl[17].val[0] = 0;
+
+ state->CH_Ctrl[18].Ctrl_Num = TG_LO_DIVVAL ;
+ state->CH_Ctrl[18].size = 4 ;
+ state->CH_Ctrl[18].addr[0] = 107;
+ state->CH_Ctrl[18].bit[0] = 3;
+ state->CH_Ctrl[18].val[0] = 0;
+ state->CH_Ctrl[18].addr[1] = 107;
+ state->CH_Ctrl[18].bit[1] = 4;
+ state->CH_Ctrl[18].val[1] = 0;
+ state->CH_Ctrl[18].addr[2] = 107;
+ state->CH_Ctrl[18].bit[2] = 5;
+ state->CH_Ctrl[18].val[2] = 0;
+ state->CH_Ctrl[18].addr[3] = 107;
+ state->CH_Ctrl[18].bit[3] = 6;
+ state->CH_Ctrl[18].val[3] = 0;
+
+ state->CH_Ctrl[19].Ctrl_Num = TG_LO_SELVAL ;
+ state->CH_Ctrl[19].size = 3 ;
+ state->CH_Ctrl[19].addr[0] = 107;
+ state->CH_Ctrl[19].bit[0] = 7;
+ state->CH_Ctrl[19].val[0] = 1;
+ state->CH_Ctrl[19].addr[1] = 106;
+ state->CH_Ctrl[19].bit[1] = 0;
+ state->CH_Ctrl[19].val[1] = 1;
+ state->CH_Ctrl[19].addr[2] = 106;
+ state->CH_Ctrl[19].bit[2] = 1;
+ state->CH_Ctrl[19].val[2] = 1;
+
+ state->CH_Ctrl[20].Ctrl_Num = TG_DIV_VAL ;
+ state->CH_Ctrl[20].size = 11 ;
+ state->CH_Ctrl[20].addr[0] = 109;
+ state->CH_Ctrl[20].bit[0] = 2;
+ state->CH_Ctrl[20].val[0] = 0;
+ state->CH_Ctrl[20].addr[1] = 109;
+ state->CH_Ctrl[20].bit[1] = 3;
+ state->CH_Ctrl[20].val[1] = 0;
+ state->CH_Ctrl[20].addr[2] = 109;
+ state->CH_Ctrl[20].bit[2] = 4;
+ state->CH_Ctrl[20].val[2] = 0;
+ state->CH_Ctrl[20].addr[3] = 109;
+ state->CH_Ctrl[20].bit[3] = 5;
+ state->CH_Ctrl[20].val[3] = 0;
+ state->CH_Ctrl[20].addr[4] = 109;
+ state->CH_Ctrl[20].bit[4] = 6;
+ state->CH_Ctrl[20].val[4] = 0;
+ state->CH_Ctrl[20].addr[5] = 109;
+ state->CH_Ctrl[20].bit[5] = 7;
+ state->CH_Ctrl[20].val[5] = 0;
+ state->CH_Ctrl[20].addr[6] = 108;
+ state->CH_Ctrl[20].bit[6] = 0;
+ state->CH_Ctrl[20].val[6] = 0;
+ state->CH_Ctrl[20].addr[7] = 108;
+ state->CH_Ctrl[20].bit[7] = 1;
+ state->CH_Ctrl[20].val[7] = 0;
+ state->CH_Ctrl[20].addr[8] = 108;
+ state->CH_Ctrl[20].bit[8] = 2;
+ state->CH_Ctrl[20].val[8] = 1;
+ state->CH_Ctrl[20].addr[9] = 108;
+ state->CH_Ctrl[20].bit[9] = 3;
+ state->CH_Ctrl[20].val[9] = 1;
+ state->CH_Ctrl[20].addr[10] = 108;
+ state->CH_Ctrl[20].bit[10] = 4;
+ state->CH_Ctrl[20].val[10] = 1;
+
+ state->CH_Ctrl[21].Ctrl_Num = TG_VCO_BIAS ;
+ state->CH_Ctrl[21].size = 6 ;
+ state->CH_Ctrl[21].addr[0] = 106;
+ state->CH_Ctrl[21].bit[0] = 2;
+ state->CH_Ctrl[21].val[0] = 0;
+ state->CH_Ctrl[21].addr[1] = 106;
+ state->CH_Ctrl[21].bit[1] = 3;
+ state->CH_Ctrl[21].val[1] = 0;
+ state->CH_Ctrl[21].addr[2] = 106;
+ state->CH_Ctrl[21].bit[2] = 4;
+ state->CH_Ctrl[21].val[2] = 0;
+ state->CH_Ctrl[21].addr[3] = 106;
+ state->CH_Ctrl[21].bit[3] = 5;
+ state->CH_Ctrl[21].val[3] = 0;
+ state->CH_Ctrl[21].addr[4] = 106;
+ state->CH_Ctrl[21].bit[4] = 6;
+ state->CH_Ctrl[21].val[4] = 0;
+ state->CH_Ctrl[21].addr[5] = 106;
+ state->CH_Ctrl[21].bit[5] = 7;
+ state->CH_Ctrl[21].val[5] = 1;
+
+ state->CH_Ctrl[22].Ctrl_Num = SEQ_EXTPOWERUP ;
+ state->CH_Ctrl[22].size = 1 ;
+ state->CH_Ctrl[22].addr[0] = 138;
+ state->CH_Ctrl[22].bit[0] = 4;
+ state->CH_Ctrl[22].val[0] = 1;
+
+ state->CH_Ctrl[23].Ctrl_Num = OVERRIDE_2 ;
+ state->CH_Ctrl[23].size = 1 ;
+ state->CH_Ctrl[23].addr[0] = 17;
+ state->CH_Ctrl[23].bit[0] = 5;
+ state->CH_Ctrl[23].val[0] = 0;
+
+ state->CH_Ctrl[24].Ctrl_Num = OVERRIDE_3 ;
+ state->CH_Ctrl[24].size = 1 ;
+ state->CH_Ctrl[24].addr[0] = 111;
+ state->CH_Ctrl[24].bit[0] = 3;
+ state->CH_Ctrl[24].val[0] = 0;
+
+ state->CH_Ctrl[25].Ctrl_Num = OVERRIDE_4 ;
+ state->CH_Ctrl[25].size = 1 ;
+ state->CH_Ctrl[25].addr[0] = 112;
+ state->CH_Ctrl[25].bit[0] = 7;
+ state->CH_Ctrl[25].val[0] = 0;
+
+ state->CH_Ctrl[26].Ctrl_Num = SEQ_FSM_PULSE ;
+ state->CH_Ctrl[26].size = 1 ;
+ state->CH_Ctrl[26].addr[0] = 136;
+ state->CH_Ctrl[26].bit[0] = 7;
+ state->CH_Ctrl[26].val[0] = 0;
+
+ state->CH_Ctrl[27].Ctrl_Num = GPIO_4B ;
+ state->CH_Ctrl[27].size = 1 ;
+ state->CH_Ctrl[27].addr[0] = 149;
+ state->CH_Ctrl[27].bit[0] = 7;
+ state->CH_Ctrl[27].val[0] = 0;
+
+ state->CH_Ctrl[28].Ctrl_Num = GPIO_3B ;
+ state->CH_Ctrl[28].size = 1 ;
+ state->CH_Ctrl[28].addr[0] = 149;
+ state->CH_Ctrl[28].bit[0] = 6;
+ state->CH_Ctrl[28].val[0] = 0;
+
+ state->CH_Ctrl[29].Ctrl_Num = GPIO_4 ;
+ state->CH_Ctrl[29].size = 1 ;
+ state->CH_Ctrl[29].addr[0] = 149;
+ state->CH_Ctrl[29].bit[0] = 5;
+ state->CH_Ctrl[29].val[0] = 1;
+
+ state->CH_Ctrl[30].Ctrl_Num = GPIO_3 ;
+ state->CH_Ctrl[30].size = 1 ;
+ state->CH_Ctrl[30].addr[0] = 149;
+ state->CH_Ctrl[30].bit[0] = 4;
+ state->CH_Ctrl[30].val[0] = 1;
+
+ state->CH_Ctrl[31].Ctrl_Num = GPIO_1B ;
+ state->CH_Ctrl[31].size = 1 ;
+ state->CH_Ctrl[31].addr[0] = 149;
+ state->CH_Ctrl[31].bit[0] = 3;
+ state->CH_Ctrl[31].val[0] = 0;
+
+ state->CH_Ctrl[32].Ctrl_Num = DAC_A_ENABLE ;
+ state->CH_Ctrl[32].size = 1 ;
+ state->CH_Ctrl[32].addr[0] = 93;
+ state->CH_Ctrl[32].bit[0] = 1;
+ state->CH_Ctrl[32].val[0] = 0;
+
+ state->CH_Ctrl[33].Ctrl_Num = DAC_B_ENABLE ;
+ state->CH_Ctrl[33].size = 1 ;
+ state->CH_Ctrl[33].addr[0] = 93;
+ state->CH_Ctrl[33].bit[0] = 0;
+ state->CH_Ctrl[33].val[0] = 0;
+
+ state->CH_Ctrl[34].Ctrl_Num = DAC_DIN_A ;
+ state->CH_Ctrl[34].size = 6 ;
+ state->CH_Ctrl[34].addr[0] = 92;
+ state->CH_Ctrl[34].bit[0] = 2;
+ state->CH_Ctrl[34].val[0] = 0;
+ state->CH_Ctrl[34].addr[1] = 92;
+ state->CH_Ctrl[34].bit[1] = 3;
+ state->CH_Ctrl[34].val[1] = 0;
+ state->CH_Ctrl[34].addr[2] = 92;
+ state->CH_Ctrl[34].bit[2] = 4;
+ state->CH_Ctrl[34].val[2] = 0;
+ state->CH_Ctrl[34].addr[3] = 92;
+ state->CH_Ctrl[34].bit[3] = 5;
+ state->CH_Ctrl[34].val[3] = 0;
+ state->CH_Ctrl[34].addr[4] = 92;
+ state->CH_Ctrl[34].bit[4] = 6;
+ state->CH_Ctrl[34].val[4] = 0;
+ state->CH_Ctrl[34].addr[5] = 92;
+ state->CH_Ctrl[34].bit[5] = 7;
+ state->CH_Ctrl[34].val[5] = 0;
+
+ state->CH_Ctrl[35].Ctrl_Num = DAC_DIN_B ;
+ state->CH_Ctrl[35].size = 6 ;
+ state->CH_Ctrl[35].addr[0] = 93;
+ state->CH_Ctrl[35].bit[0] = 2;
+ state->CH_Ctrl[35].val[0] = 0;
+ state->CH_Ctrl[35].addr[1] = 93;
+ state->CH_Ctrl[35].bit[1] = 3;
+ state->CH_Ctrl[35].val[1] = 0;
+ state->CH_Ctrl[35].addr[2] = 93;
+ state->CH_Ctrl[35].bit[2] = 4;
+ state->CH_Ctrl[35].val[2] = 0;
+ state->CH_Ctrl[35].addr[3] = 93;
+ state->CH_Ctrl[35].bit[3] = 5;
+ state->CH_Ctrl[35].val[3] = 0;
+ state->CH_Ctrl[35].addr[4] = 93;
+ state->CH_Ctrl[35].bit[4] = 6;
+ state->CH_Ctrl[35].val[4] = 0;
+ state->CH_Ctrl[35].addr[5] = 93;
+ state->CH_Ctrl[35].bit[5] = 7;
+ state->CH_Ctrl[35].val[5] = 0;
+
+#ifdef _MXL_PRODUCTION
+ state->CH_Ctrl[36].Ctrl_Num = RFSYN_EN_DIV ;
+ state->CH_Ctrl[36].size = 1 ;
+ state->CH_Ctrl[36].addr[0] = 109;
+ state->CH_Ctrl[36].bit[0] = 1;
+ state->CH_Ctrl[36].val[0] = 1;
+
+ state->CH_Ctrl[37].Ctrl_Num = RFSYN_DIVM ;
+ state->CH_Ctrl[37].size = 2 ;
+ state->CH_Ctrl[37].addr[0] = 112;
+ state->CH_Ctrl[37].bit[0] = 5;
+ state->CH_Ctrl[37].val[0] = 0;
+ state->CH_Ctrl[37].addr[1] = 112;
+ state->CH_Ctrl[37].bit[1] = 6;
+ state->CH_Ctrl[37].val[1] = 0;
+
+ state->CH_Ctrl[38].Ctrl_Num = DN_BYPASS_AGC_I2C ;
+ state->CH_Ctrl[38].size = 1 ;
+ state->CH_Ctrl[38].addr[0] = 65;
+ state->CH_Ctrl[38].bit[0] = 1;
+ state->CH_Ctrl[38].val[0] = 0;
+#endif
+
+ return 0 ;
+}
+
+static void InitTunerControls(struct dvb_frontend *fe)
+{
+ MXL5005_RegisterInit(fe);
+ MXL5005_ControlInit(fe);
+#ifdef _MXL_INTERNAL
+ MXL5005_MXLControlInit(fe);
+#endif
+}
+
+static u16 MXL5005_TunerConfig(struct dvb_frontend *fe,
+ u8 Mode, /* 0: Analog Mode ; 1: Digital Mode */
+ u8 IF_mode, /* for Analog Mode, 0: zero IF; 1: low IF */
+ u32 Bandwidth, /* filter channel bandwidth (6, 7, 8) */
+ u32 IF_out, /* Desired IF Out Frequency */
+ u32 Fxtal, /* XTAL Frequency */
+ u8 AGC_Mode, /* AGC Mode - Dual AGC: 0, Single AGC: 1 */
+ u16 TOP, /* 0: Dual AGC; Value: take over point */
+ u16 IF_OUT_LOAD, /* IF Out Load Resistor (200 / 300 Ohms) */
+ u8 CLOCK_OUT, /* 0: turn off clk out; 1: turn on clock out */
+ u8 DIV_OUT, /* 0: Div-1; 1: Div-4 */
+ u8 CAPSELECT, /* 0: disable On-Chip pulling cap; 1: enable */
+ u8 EN_RSSI, /* 0: disable RSSI; 1: enable RSSI */
+
+ /* Modulation Type; */
+ /* 0 - Default; 1 - DVB-T; 2 - ATSC; 3 - QAM; 4 - Analog Cable */
+ u8 Mod_Type,
+
+ /* Tracking Filter */
+ /* 0 - Default; 1 - Off; 2 - Type C; 3 - Type C-H */
+ u8 TF_Type
+ )
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ u16 status = 0;
+
+ state->Mode = Mode;
+ state->IF_Mode = IF_mode;
+ state->Chan_Bandwidth = Bandwidth;
+ state->IF_OUT = IF_out;
+ state->Fxtal = Fxtal;
+ state->AGC_Mode = AGC_Mode;
+ state->TOP = TOP;
+ state->IF_OUT_LOAD = IF_OUT_LOAD;
+ state->CLOCK_OUT = CLOCK_OUT;
+ state->DIV_OUT = DIV_OUT;
+ state->CAPSELECT = CAPSELECT;
+ state->EN_RSSI = EN_RSSI;
+ state->Mod_Type = Mod_Type;
+ state->TF_Type = TF_Type;
+
+ /* Initialize all the controls and registers */
+ InitTunerControls(fe);
+
+ /* Synthesizer LO frequency calculation */
+ MXL_SynthIFLO_Calc(fe);
+
+ return status;
+}
+
+static void MXL_SynthIFLO_Calc(struct dvb_frontend *fe)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ if (state->Mode == 1) /* Digital Mode */
+ state->IF_LO = state->IF_OUT;
+ else /* Analog Mode */ {
+ if (state->IF_Mode == 0) /* Analog Zero IF mode */
+ state->IF_LO = state->IF_OUT + 400000;
+ else /* Analog Low IF mode */
+ state->IF_LO = state->IF_OUT + state->Chan_Bandwidth/2;
+ }
+}
+
+static void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+
+ if (state->Mode == 1) /* Digital Mode */ {
+ /* remove 20.48MHz setting for 2.6.10 */
+ state->RF_LO = state->RF_IN;
+ /* change for 2.6.6 */
+ state->TG_LO = state->RF_IN - 750000;
+ } else /* Analog Mode */ {
+ if (state->IF_Mode == 0) /* Analog Zero IF mode */ {
+ state->RF_LO = state->RF_IN - 400000;
+ state->TG_LO = state->RF_IN - 1750000;
+ } else /* Analog Low IF mode */ {
+ state->RF_LO = state->RF_IN - state->Chan_Bandwidth/2;
+ state->TG_LO = state->RF_IN -
+ state->Chan_Bandwidth + 500000;
+ }
+ }
+}
+
+static u16 MXL_OverwriteICDefault(struct dvb_frontend *fe)
+{
+ u16 status = 0;
+
+ status += MXL_ControlWrite(fe, OVERRIDE_1, 1);
+ status += MXL_ControlWrite(fe, OVERRIDE_2, 1);
+ status += MXL_ControlWrite(fe, OVERRIDE_3, 1);
+ status += MXL_ControlWrite(fe, OVERRIDE_4, 1);
+
+ return status;
+}
+
+static u16 MXL_BlockInit(struct dvb_frontend *fe)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ u16 status = 0;
+
+ status += MXL_OverwriteICDefault(fe);
+
+ /* Downconverter Control Dig Ana */
+ status += MXL_ControlWrite(fe, DN_IQTN_AMP_CUT, state->Mode ? 1 : 0);
+
+ /* Filter Control Dig Ana */
+ status += MXL_ControlWrite(fe, BB_MODE, state->Mode ? 0 : 1);
+ status += MXL_ControlWrite(fe, BB_BUF, state->Mode ? 3 : 2);
+ status += MXL_ControlWrite(fe, BB_BUF_OA, state->Mode ? 1 : 0);
+ status += MXL_ControlWrite(fe, BB_IQSWAP, state->Mode ? 0 : 1);
+ status += MXL_ControlWrite(fe, BB_INITSTATE_DLPF_TUNE, 0);
+
+ /* Initialize Low-Pass Filter */
+ if (state->Mode) { /* Digital Mode */
+ switch (state->Chan_Bandwidth) {
+ case 8000000:
+ status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 0);
+ break;
+ case 7000000:
+ status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 2);
+ break;
+ case 6000000:
+ status += MXL_ControlWrite(fe,
+ BB_DLPF_BANDSEL, 3);
+ break;
+ }
+ } else { /* Analog Mode */
+ switch (state->Chan_Bandwidth) {
+ case 8000000: /* Low Zero */
+ status += MXL_ControlWrite(fe, BB_ALPF_BANDSELECT,
+ (state->IF_Mode ? 0 : 3));
+ break;
+ case 7000000:
+ status += MXL_ControlWrite(fe, BB_ALPF_BANDSELECT,
+ (state->IF_Mode ? 1 : 4));
+ break;
+ case 6000000:
+ status += MXL_ControlWrite(fe, BB_ALPF_BANDSELECT,
+ (state->IF_Mode ? 2 : 5));
+ break;
+ }
+ }
+
+ /* Charge Pump Control Dig Ana */
+ status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, state->Mode ? 5 : 8);
+ status += MXL_ControlWrite(fe,
+ RFSYN_EN_CHP_HIGAIN, state->Mode ? 1 : 1);
+ status += MXL_ControlWrite(fe, EN_CHP_LIN_B, state->Mode ? 0 : 0);
+
+ /* AGC TOP Control */
+ if (state->AGC_Mode == 0) /* Dual AGC */ {
+ status += MXL_ControlWrite(fe, AGC_IF, 15);
+ status += MXL_ControlWrite(fe, AGC_RF, 15);
+ } else /* Single AGC Mode Dig Ana */
+ status += MXL_ControlWrite(fe, AGC_RF, state->Mode ? 15 : 12);
+
+ if (state->TOP == 55) /* TOP == 5.5 */
+ status += MXL_ControlWrite(fe, AGC_IF, 0x0);
+
+ if (state->TOP == 72) /* TOP == 7.2 */
+ status += MXL_ControlWrite(fe, AGC_IF, 0x1);
+
+ if (state->TOP == 92) /* TOP == 9.2 */
+ status += MXL_ControlWrite(fe, AGC_IF, 0x2);
+
+ if (state->TOP == 110) /* TOP == 11.0 */
+ status += MXL_ControlWrite(fe, AGC_IF, 0x3);
+
+ if (state->TOP == 129) /* TOP == 12.9 */
+ status += MXL_ControlWrite(fe, AGC_IF, 0x4);
+
+ if (state->TOP == 147) /* TOP == 14.7 */
+ status += MXL_ControlWrite(fe, AGC_IF, 0x5);
+
+ if (state->TOP == 168) /* TOP == 16.8 */
+ status += MXL_ControlWrite(fe, AGC_IF, 0x6);
+
+ if (state->TOP == 194) /* TOP == 19.4 */
+ status += MXL_ControlWrite(fe, AGC_IF, 0x7);
+
+ if (state->TOP == 212) /* TOP == 21.2 */
+ status += MXL_ControlWrite(fe, AGC_IF, 0x9);
+
+ if (state->TOP == 232) /* TOP == 23.2 */
+ status += MXL_ControlWrite(fe, AGC_IF, 0xA);
+
+ if (state->TOP == 252) /* TOP == 25.2 */
+ status += MXL_ControlWrite(fe, AGC_IF, 0xB);
+
+ if (state->TOP == 271) /* TOP == 27.1 */
+ status += MXL_ControlWrite(fe, AGC_IF, 0xC);
+
+ if (state->TOP == 292) /* TOP == 29.2 */
+ status += MXL_ControlWrite(fe, AGC_IF, 0xD);
+
+ if (state->TOP == 317) /* TOP == 31.7 */
+ status += MXL_ControlWrite(fe, AGC_IF, 0xE);
+
+ if (state->TOP == 349) /* TOP == 34.9 */
+ status += MXL_ControlWrite(fe, AGC_IF, 0xF);
+
+ /* IF Synthesizer Control */
+ status += MXL_IFSynthInit(fe);
+
+ /* IF UpConverter Control */
+ if (state->IF_OUT_LOAD == 200) {
+ status += MXL_ControlWrite(fe, DRV_RES_SEL, 6);
+ status += MXL_ControlWrite(fe, I_DRIVER, 2);
+ }
+ if (state->IF_OUT_LOAD == 300) {
+ status += MXL_ControlWrite(fe, DRV_RES_SEL, 4);
+ status += MXL_ControlWrite(fe, I_DRIVER, 1);
+ }
+
+ /* Anti-Alias Filtering Control
+ * initialise Anti-Aliasing Filter
+ */
+ if (state->Mode) { /* Digital Mode */
+ if (state->IF_OUT >= 4000000UL && state->IF_OUT <= 6280000UL) {
+ status += MXL_ControlWrite(fe, EN_AAF, 1);
+ status += MXL_ControlWrite(fe, EN_3P, 1);
+ status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
+ status += MXL_ControlWrite(fe, SEL_AAF_BAND, 0);
+ }
+ if ((state->IF_OUT == 36125000UL) ||
+ (state->IF_OUT == 36150000UL)) {
+ status += MXL_ControlWrite(fe, EN_AAF, 1);
+ status += MXL_ControlWrite(fe, EN_3P, 1);
+ status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
+ status += MXL_ControlWrite(fe, SEL_AAF_BAND, 1);
+ }
+ if (state->IF_OUT > 36150000UL) {
+ status += MXL_ControlWrite(fe, EN_AAF, 0);
+ status += MXL_ControlWrite(fe, EN_3P, 1);
+ status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
+ status += MXL_ControlWrite(fe, SEL_AAF_BAND, 1);
+ }
+ } else { /* Analog Mode */
+ if (state->IF_OUT >= 4000000UL && state->IF_OUT <= 5000000UL) {
+ status += MXL_ControlWrite(fe, EN_AAF, 1);
+ status += MXL_ControlWrite(fe, EN_3P, 1);
+ status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
+ status += MXL_ControlWrite(fe, SEL_AAF_BAND, 0);
+ }
+ if (state->IF_OUT > 5000000UL) {
+ status += MXL_ControlWrite(fe, EN_AAF, 0);
+ status += MXL_ControlWrite(fe, EN_3P, 0);
+ status += MXL_ControlWrite(fe, EN_AUX_3P, 0);
+ status += MXL_ControlWrite(fe, SEL_AAF_BAND, 0);
+ }
+ }
+
+ /* Demod Clock Out */
+ if (state->CLOCK_OUT)
+ status += MXL_ControlWrite(fe, SEQ_ENCLK16_CLK_OUT, 1);
+ else
+ status += MXL_ControlWrite(fe, SEQ_ENCLK16_CLK_OUT, 0);
+
+ if (state->DIV_OUT == 1)
+ status += MXL_ControlWrite(fe, SEQ_SEL4_16B, 1);
+ if (state->DIV_OUT == 0)
+ status += MXL_ControlWrite(fe, SEQ_SEL4_16B, 0);
+
+ /* Crystal Control */
+ if (state->CAPSELECT)
+ status += MXL_ControlWrite(fe, XTAL_CAPSELECT, 1);
+ else
+ status += MXL_ControlWrite(fe, XTAL_CAPSELECT, 0);
+
+ if (state->Fxtal >= 12000000UL && state->Fxtal <= 16000000UL)
+ status += MXL_ControlWrite(fe, IF_SEL_DBL, 1);
+ if (state->Fxtal > 16000000UL && state->Fxtal <= 32000000UL)
+ status += MXL_ControlWrite(fe, IF_SEL_DBL, 0);
+
+ if (state->Fxtal >= 12000000UL && state->Fxtal <= 22000000UL)
+ status += MXL_ControlWrite(fe, RFSYN_R_DIV, 3);
+ if (state->Fxtal > 22000000UL && state->Fxtal <= 32000000UL)
+ status += MXL_ControlWrite(fe, RFSYN_R_DIV, 0);
+
+ /* Misc Controls */
+ if (state->Mode == 0 && state->IF_Mode == 1) /* Analog LowIF mode */
+ status += MXL_ControlWrite(fe, SEQ_EXTIQFSMPULSE, 0);
+ else
+ status += MXL_ControlWrite(fe, SEQ_EXTIQFSMPULSE, 1);
+
+ /* status += MXL_ControlRead(fe, IF_DIVVAL, &IF_DIVVAL_Val); */
+
+ /* Set TG_R_DIV */
+ status += MXL_ControlWrite(fe, TG_R_DIV,
+ MXL_Ceiling(state->Fxtal, 1000000));
+
+ /* Apply Default value to BB_INITSTATE_DLPF_TUNE */
+
+ /* RSSI Control */
+ if (state->EN_RSSI) {
+ status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+ status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+ status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
+ status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+
+ /* RSSI reference point */
+ status += MXL_ControlWrite(fe, RFA_RSSI_REF, 2);
+ status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 3);
+ status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 1);
+
+ /* TOP point */
+ status += MXL_ControlWrite(fe, RFA_FLR, 0);
+ status += MXL_ControlWrite(fe, RFA_CEIL, 12);
+ }
+
+ /* Modulation type bit settings
+ * Override the control values preset
+ */
+ if (state->Mod_Type == MXL_DVBT) /* DVB-T Mode */ {
+ state->AGC_Mode = 1; /* Single AGC Mode */
+
+ /* Enable RSSI */
+ status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+ status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+ status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
+ status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+
+ /* RSSI reference point */
+ status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
+ status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
+ status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 1);
+
+ /* TOP point */
+ status += MXL_ControlWrite(fe, RFA_FLR, 2);
+ status += MXL_ControlWrite(fe, RFA_CEIL, 13);
+ if (state->IF_OUT <= 6280000UL) /* Low IF */
+ status += MXL_ControlWrite(fe, BB_IQSWAP, 0);
+ else /* High IF */
+ status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
+
+ }
+ if (state->Mod_Type == MXL_ATSC) /* ATSC Mode */ {
+ state->AGC_Mode = 1; /* Single AGC Mode */
+
+ /* Enable RSSI */
+ status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+ status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+ status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
+ status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+
+ /* RSSI reference point */
+ status += MXL_ControlWrite(fe, RFA_RSSI_REF, 2);
+ status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 4);
+ status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 1);
+
+ /* TOP point */
+ status += MXL_ControlWrite(fe, RFA_FLR, 2);
+ status += MXL_ControlWrite(fe, RFA_CEIL, 13);
+ status += MXL_ControlWrite(fe, BB_INITSTATE_DLPF_TUNE, 1);
+ /* Low Zero */
+ status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 5);
+
+ if (state->IF_OUT <= 6280000UL) /* Low IF */
+ status += MXL_ControlWrite(fe, BB_IQSWAP, 0);
+ else /* High IF */
+ status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
+ }
+ if (state->Mod_Type == MXL_QAM) /* QAM Mode */ {
+ state->Mode = MXL_DIGITAL_MODE;
+
+ /* state->AGC_Mode = 1; */ /* Single AGC Mode */
+
+ /* Disable RSSI */ /* change here for v2.6.5 */
+ status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+ status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+ status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
+ status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+
+ /* RSSI reference point */
+ status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
+ status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
+ status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 2);
+ /* change here for v2.6.5 */
+ status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
+
+ if (state->IF_OUT <= 6280000UL) /* Low IF */
+ status += MXL_ControlWrite(fe, BB_IQSWAP, 0);
+ else /* High IF */
+ status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
+ status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2);
+
+ }
+ if (state->Mod_Type == MXL_ANALOG_CABLE) {
+ /* Analog Cable Mode */
+ /* state->Mode = MXL_DIGITAL_MODE; */
+
+ state->AGC_Mode = 1; /* Single AGC Mode */
+
+ /* Disable RSSI */
+ status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+ status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+ status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
+ status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+ /* change for 2.6.3 */
+ status += MXL_ControlWrite(fe, AGC_IF, 1);
+ status += MXL_ControlWrite(fe, AGC_RF, 15);
+ status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
+ }
+
+ if (state->Mod_Type == MXL_ANALOG_OTA) {
+ /* Analog OTA Terrestrial mode add for 2.6.7 */
+ /* state->Mode = MXL_ANALOG_MODE; */
+
+ /* Enable RSSI */
+ status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+ status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+ status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
+ status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+
+ /* RSSI reference point */
+ status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
+ status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
+ status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 2);
+ status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
+ status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
+ }
+
+ /* RSSI disable */
+ if (state->EN_RSSI == 0) {
+ status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+ status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+ status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
+ status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+ }
+
+ return status;
+}
+
+static u16 MXL_IFSynthInit(struct dvb_frontend *fe)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ u16 status = 0 ;
+ u32 Fref = 0 ;
+ u32 Kdbl, intModVal ;
+ u32 fracModVal ;
+ Kdbl = 2 ;
+
+ if (state->Fxtal >= 12000000UL && state->Fxtal <= 16000000UL)
+ Kdbl = 2 ;
+ if (state->Fxtal > 16000000UL && state->Fxtal <= 32000000UL)
+ Kdbl = 1 ;
+
+ /* IF Synthesizer Control */
+ if (state->Mode == 0 && state->IF_Mode == 1) /* Analog Low IF mode */ {
+ if (state->IF_LO == 41000000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+ Fref = 328000000UL ;
+ }
+ if (state->IF_LO == 47000000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 376000000UL ;
+ }
+ if (state->IF_LO == 54000000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x10);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+ Fref = 324000000UL ;
+ }
+ if (state->IF_LO == 60000000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x10);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 360000000UL ;
+ }
+ if (state->IF_LO == 39250000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+ Fref = 314000000UL ;
+ }
+ if (state->IF_LO == 39650000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+ Fref = 317200000UL ;
+ }
+ if (state->IF_LO == 40150000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+ Fref = 321200000UL ;
+ }
+ if (state->IF_LO == 40650000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+ Fref = 325200000UL ;
+ }
+ }
+
+ if (state->Mode || (state->Mode == 0 && state->IF_Mode == 0)) {
+ if (state->IF_LO == 57000000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x10);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 342000000UL ;
+ }
+ if (state->IF_LO == 44000000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 352000000UL ;
+ }
+ if (state->IF_LO == 43750000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 350000000UL ;
+ }
+ if (state->IF_LO == 36650000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 366500000UL ;
+ }
+ if (state->IF_LO == 36150000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 361500000UL ;
+ }
+ if (state->IF_LO == 36000000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 360000000UL ;
+ }
+ if (state->IF_LO == 35250000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 352500000UL ;
+ }
+ if (state->IF_LO == 34750000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 347500000UL ;
+ }
+ if (state->IF_LO == 6280000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x07);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 376800000UL ;
+ }
+ if (state->IF_LO == 5000000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x09);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 360000000UL ;
+ }
+ if (state->IF_LO == 4500000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x06);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 360000000UL ;
+ }
+ if (state->IF_LO == 4570000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x06);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 365600000UL ;
+ }
+ if (state->IF_LO == 4000000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x05);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 360000000UL ;
+ }
+ if (state->IF_LO == 57400000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x10);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 344400000UL ;
+ }
+ if (state->IF_LO == 44400000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 355200000UL ;
+ }
+ if (state->IF_LO == 44150000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 353200000UL ;
+ }
+ if (state->IF_LO == 37050000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 370500000UL ;
+ }
+ if (state->IF_LO == 36550000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 365500000UL ;
+ }
+ if (state->IF_LO == 36125000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 361250000UL ;
+ }
+ if (state->IF_LO == 6000000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x07);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 360000000UL ;
+ }
+ if (state->IF_LO == 5400000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x07);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+ Fref = 324000000UL ;
+ }
+ if (state->IF_LO == 5380000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x07);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
+ Fref = 322800000UL ;
+ }
+ if (state->IF_LO == 5200000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x09);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 374400000UL ;
+ }
+ if (state->IF_LO == 4900000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x09);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 352800000UL ;
+ }
+ if (state->IF_LO == 4400000UL) {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x06);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 352000000UL ;
+ }
+ if (state->IF_LO == 4063000UL) /* add for 2.6.8 */ {
+ status += MXL_ControlWrite(fe, IF_DIVVAL, 0x05);
+ status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
+ Fref = 365670000UL ;
+ }
+ }
+ /* CHCAL_INT_MOD_IF */
+ /* CHCAL_FRAC_MOD_IF */
+ intModVal = Fref / (state->Fxtal * Kdbl/2);
+ status += MXL_ControlWrite(fe, CHCAL_INT_MOD_IF, intModVal);
+
+ fracModVal = (2<<15)*(Fref/1000 - (state->Fxtal/1000 * Kdbl/2) *
+ intModVal);
+
+ fracModVal = fracModVal / ((state->Fxtal * Kdbl/2)/1000);
+ status += MXL_ControlWrite(fe, CHCAL_FRAC_MOD_IF, fracModVal);
+
+ return status ;
+}
+
+static u32 MXL_GetXtalInt(u32 Xtal_Freq)
+{
+ if ((Xtal_Freq % 1000000) == 0)
+ return (Xtal_Freq / 10000);
+ else
+ return (((Xtal_Freq / 1000000) + 1)*100);
+}
+
+static u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ u16 status = 0;
+ u32 divider_val, E3, E4, E5, E5A;
+ u32 Fmax, Fmin, FmaxBin, FminBin;
+ u32 Kdbl_RF = 2;
+ u32 tg_divval;
+ u32 tg_lo;
+ u32 Xtal_Int;
+
+ u32 Fref_TG;
+ u32 Fvco;
+
+ Xtal_Int = MXL_GetXtalInt(state->Fxtal);
+
+ state->RF_IN = RF_Freq;
+
+ MXL_SynthRFTGLO_Calc(fe);
+
+ if (state->Fxtal >= 12000000UL && state->Fxtal <= 22000000UL)
+ Kdbl_RF = 2;
+ if (state->Fxtal > 22000000 && state->Fxtal <= 32000000)
+ Kdbl_RF = 1;
+
+ /* Downconverter Controls
+ * Look-Up Table Implementation for:
+ * DN_POLY
+ * DN_RFGAIN
+ * DN_CAP_RFLPF
+ * DN_EN_VHFUHFBAR
+ * DN_GAIN_ADJUST
+ * Change the boundary reference from RF_IN to RF_LO
+ */
+ if (state->RF_LO < 40000000UL)
+ return -1;
+
+ if (state->RF_LO >= 40000000UL && state->RF_LO <= 75000000UL) {
+ status += MXL_ControlWrite(fe, DN_POLY, 2);
+ status += MXL_ControlWrite(fe, DN_RFGAIN, 3);
+ status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 423);
+ status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 1);
+ status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 1);
+ }
+ if (state->RF_LO > 75000000UL && state->RF_LO <= 100000000UL) {
+ status += MXL_ControlWrite(fe, DN_POLY, 3);
+ status += MXL_ControlWrite(fe, DN_RFGAIN, 3);
+ status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 222);
+ status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 1);
+ status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 1);
+ }
+ if (state->RF_LO > 100000000UL && state->RF_LO <= 150000000UL) {
+ status += MXL_ControlWrite(fe, DN_POLY, 3);
+ status += MXL_ControlWrite(fe, DN_RFGAIN, 3);
+ status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 147);
+ status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 1);
+ status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 2);
+ }
+ if (state->RF_LO > 150000000UL && state->RF_LO <= 200000000UL) {
+ status += MXL_ControlWrite(fe, DN_POLY, 3);
+ status += MXL_ControlWrite(fe, DN_RFGAIN, 3);
+ status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 9);
+ status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 1);
+ status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 2);
+ }
+ if (state->RF_LO > 200000000UL && state->RF_LO <= 300000000UL) {
+ status += MXL_ControlWrite(fe, DN_POLY, 3);
+ status += MXL_ControlWrite(fe, DN_RFGAIN, 3);
+ status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 0);
+ status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 1);
+ status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 3);
+ }
+ if (state->RF_LO > 300000000UL && state->RF_LO <= 650000000UL) {
+ status += MXL_ControlWrite(fe, DN_POLY, 3);
+ status += MXL_ControlWrite(fe, DN_RFGAIN, 1);
+ status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 0);
+ status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 0);
+ status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 3);
+ }
+ if (state->RF_LO > 650000000UL && state->RF_LO <= 900000000UL) {
+ status += MXL_ControlWrite(fe, DN_POLY, 3);
+ status += MXL_ControlWrite(fe, DN_RFGAIN, 2);
+ status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 0);
+ status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 0);
+ status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 3);
+ }
+ if (state->RF_LO > 900000000UL)
+ return -1;
+
+ /* DN_IQTNBUF_AMP */
+ /* DN_IQTNGNBFBIAS_BST */
+ if (state->RF_LO >= 40000000UL && state->RF_LO <= 75000000UL) {
+ status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
+ status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
+ }
+ if (state->RF_LO > 75000000UL && state->RF_LO <= 100000000UL) {
+ status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
+ status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
+ }
+ if (state->RF_LO > 100000000UL && state->RF_LO <= 150000000UL) {
+ status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
+ status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
+ }
+ if (state->RF_LO > 150000000UL && state->RF_LO <= 200000000UL) {
+ status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
+ status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
+ }
+ if (state->RF_LO > 200000000UL && state->RF_LO <= 300000000UL) {
+ status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
+ status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
+ }
+ if (state->RF_LO > 300000000UL && state->RF_LO <= 400000000UL) {
+ status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
+ status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
+ }
+ if (state->RF_LO > 400000000UL && state->RF_LO <= 450000000UL) {
+ status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
+ status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
+ }
+ if (state->RF_LO > 450000000UL && state->RF_LO <= 500000000UL) {
+ status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
+ status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
+ }
+ if (state->RF_LO > 500000000UL && state->RF_LO <= 550000000UL) {
+ status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
+ status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
+ }
+ if (state->RF_LO > 550000000UL && state->RF_LO <= 600000000UL) {
+ status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
+ status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
+ }
+ if (state->RF_LO > 600000000UL && state->RF_LO <= 650000000UL) {
+ status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
+ status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
+ }
+ if (state->RF_LO > 650000000UL && state->RF_LO <= 700000000UL) {
+ status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
+ status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
+ }
+ if (state->RF_LO > 700000000UL && state->RF_LO <= 750000000UL) {
+ status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
+ status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
+ }
+ if (state->RF_LO > 750000000UL && state->RF_LO <= 800000000UL) {
+ status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
+ status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
+ }
+ if (state->RF_LO > 800000000UL && state->RF_LO <= 850000000UL) {
+ status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 10);
+ status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 1);
+ }
+ if (state->RF_LO > 850000000UL && state->RF_LO <= 900000000UL) {
+ status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 10);
+ status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 1);
+ }
+
+ /*
+ * Set RF Synth and LO Path Control
+ *
+ * Look-Up table implementation for:
+ * RFSYN_EN_OUTMUX
+ * RFSYN_SEL_VCO_OUT
+ * RFSYN_SEL_VCO_HI
+ * RFSYN_SEL_DIVM
+ * RFSYN_RF_DIV_BIAS
+ * DN_SEL_FREQ
+ *
+ * Set divider_val, Fmax, Fmix to use in Equations
+ */
+ FminBin = 28000000UL ;
+ FmaxBin = 42500000UL ;
+ if (state->RF_LO >= 40000000UL && state->RF_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+ status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+ status += MXL_ControlWrite(fe, DN_SEL_FREQ, 1);
+ divider_val = 64 ;
+ Fmax = FmaxBin ;
+ Fmin = FminBin ;
+ }
+ FminBin = 42500000UL ;
+ FmaxBin = 56000000UL ;
+ if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+ status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+ status += MXL_ControlWrite(fe, DN_SEL_FREQ, 1);
+ divider_val = 64 ;
+ Fmax = FmaxBin ;
+ Fmin = FminBin ;
+ }
+ FminBin = 56000000UL ;
+ FmaxBin = 85000000UL ;
+ if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+ status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+ status += MXL_ControlWrite(fe, DN_SEL_FREQ, 1);
+ divider_val = 32 ;
+ Fmax = FmaxBin ;
+ Fmin = FminBin ;
+ }
+ FminBin = 85000000UL ;
+ FmaxBin = 112000000UL ;
+ if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+ status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+ status += MXL_ControlWrite(fe, DN_SEL_FREQ, 1);
+ divider_val = 32 ;
+ Fmax = FmaxBin ;
+ Fmin = FminBin ;
+ }
+ FminBin = 112000000UL ;
+ FmaxBin = 170000000UL ;
+ if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+ status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+ status += MXL_ControlWrite(fe, DN_SEL_FREQ, 2);
+ divider_val = 16 ;
+ Fmax = FmaxBin ;
+ Fmin = FminBin ;
+ }
+ FminBin = 170000000UL ;
+ FmaxBin = 225000000UL ;
+ if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+ status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+ status += MXL_ControlWrite(fe, DN_SEL_FREQ, 2);
+ divider_val = 16 ;
+ Fmax = FmaxBin ;
+ Fmin = FminBin ;
+ }
+ FminBin = 225000000UL ;
+ FmaxBin = 300000000UL ;
+ if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+ status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+ status += MXL_ControlWrite(fe, DN_SEL_FREQ, 4);
+ divider_val = 8 ;
+ Fmax = 340000000UL ;
+ Fmin = FminBin ;
+ }
+ FminBin = 300000000UL ;
+ FmaxBin = 340000000UL ;
+ if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+ status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+ status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
+ divider_val = 8 ;
+ Fmax = FmaxBin ;
+ Fmin = 225000000UL ;
+ }
+ FminBin = 340000000UL ;
+ FmaxBin = 450000000UL ;
+ if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+ status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 2);
+ status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
+ divider_val = 8 ;
+ Fmax = FmaxBin ;
+ Fmin = FminBin ;
+ }
+ FminBin = 450000000UL ;
+ FmaxBin = 680000000UL ;
+ if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 1);
+ status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+ status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
+ divider_val = 4 ;
+ Fmax = FmaxBin ;
+ Fmin = FminBin ;
+ }
+ FminBin = 680000000UL ;
+ FmaxBin = 900000000UL ;
+ if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 1);
+ status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+ status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
+ divider_val = 4 ;
+ Fmax = FmaxBin ;
+ Fmin = FminBin ;
+ }
+
+ /* CHCAL_INT_MOD_RF
+ * CHCAL_FRAC_MOD_RF
+ * RFSYN_LPF_R
+ * CHCAL_EN_INT_RF
+ */
+ /* Equation E3 RFSYN_VCO_BIAS */
+ E3 = (((Fmax-state->RF_LO)/1000)*32)/((Fmax-Fmin)/1000) + 8 ;
+ status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, E3);
+
+ /* Equation E4 CHCAL_INT_MOD_RF */
+ E4 = (state->RF_LO*divider_val/1000)/(2*state->Fxtal*Kdbl_RF/1000);
+ MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, E4);
+
+ /* Equation E5 CHCAL_FRAC_MOD_RF CHCAL_EN_INT_RF */
+ E5 = ((2<<17)*(state->RF_LO/10000*divider_val -
+ (E4*(2*state->Fxtal*Kdbl_RF)/10000))) /
+ (2*state->Fxtal*Kdbl_RF/10000);
+
+ status += MXL_ControlWrite(fe, CHCAL_FRAC_MOD_RF, E5);
+
+ /* Equation E5A RFSYN_LPF_R */
+ E5A = (((Fmax - state->RF_LO)/1000)*4/((Fmax-Fmin)/1000)) + 1 ;
+ status += MXL_ControlWrite(fe, RFSYN_LPF_R, E5A);
+
+ /* Euqation E5B CHCAL_EN_INIT_RF */
+ status += MXL_ControlWrite(fe, CHCAL_EN_INT_RF, ((E5 == 0) ? 1 : 0));
+ /*if (E5 == 0)
+ * status += MXL_ControlWrite(fe, CHCAL_EN_INT_RF, 1);
+ *else
+ * status += MXL_ControlWrite(fe, CHCAL_FRAC_MOD_RF, E5);
+ */
+
+ /*
+ * Set TG Synth
+ *
+ * Look-Up table implementation for:
+ * TG_LO_DIVVAL
+ * TG_LO_SELVAL
+ *
+ * Set divider_val, Fmax, Fmix to use in Equations
+ */
+ if (state->TG_LO < 33000000UL)
+ return -1;
+
+ FminBin = 33000000UL ;
+ FmaxBin = 50000000UL ;
+ if (state->TG_LO >= FminBin && state->TG_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x6);
+ status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x0);
+ divider_val = 36 ;
+ Fmax = FmaxBin ;
+ Fmin = FminBin ;
+ }
+ FminBin = 50000000UL ;
+ FmaxBin = 67000000UL ;
+ if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x1);
+ status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x0);
+ divider_val = 24 ;
+ Fmax = FmaxBin ;
+ Fmin = FminBin ;
+ }
+ FminBin = 67000000UL ;
+ FmaxBin = 100000000UL ;
+ if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0xC);
+ status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x2);
+ divider_val = 18 ;
+ Fmax = FmaxBin ;
+ Fmin = FminBin ;
+ }
+ FminBin = 100000000UL ;
+ FmaxBin = 150000000UL ;
+ if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x8);
+ status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x2);
+ divider_val = 12 ;
+ Fmax = FmaxBin ;
+ Fmin = FminBin ;
+ }
+ FminBin = 150000000UL ;
+ FmaxBin = 200000000UL ;
+ if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x0);
+ status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x2);
+ divider_val = 8 ;
+ Fmax = FmaxBin ;
+ Fmin = FminBin ;
+ }
+ FminBin = 200000000UL ;
+ FmaxBin = 300000000UL ;
+ if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x8);
+ status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x3);
+ divider_val = 6 ;
+ Fmax = FmaxBin ;
+ Fmin = FminBin ;
+ }
+ FminBin = 300000000UL ;
+ FmaxBin = 400000000UL ;
+ if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x0);
+ status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x3);
+ divider_val = 4 ;
+ Fmax = FmaxBin ;
+ Fmin = FminBin ;
+ }
+ FminBin = 400000000UL ;
+ FmaxBin = 600000000UL ;
+ if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x8);
+ status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x7);
+ divider_val = 3 ;
+ Fmax = FmaxBin ;
+ Fmin = FminBin ;
+ }
+ FminBin = 600000000UL ;
+ FmaxBin = 900000000UL ;
+ if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
+ status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x0);
+ status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x7);
+ divider_val = 2 ;
+ Fmax = FmaxBin ;
+ Fmin = FminBin ;
+ }
+
+ /* TG_DIV_VAL */
+ tg_divval = (state->TG_LO*divider_val/100000) *
+ (MXL_Ceiling(state->Fxtal, 1000000) * 100) /
+ (state->Fxtal/1000);
+
+ status += MXL_ControlWrite(fe, TG_DIV_VAL, tg_divval);
+
+ if (state->TG_LO > 600000000UL)
+ status += MXL_ControlWrite(fe, TG_DIV_VAL, tg_divval + 1);
+
+ Fmax = 1800000000UL ;
+ Fmin = 1200000000UL ;
+
+ /* prevent overflow of 32 bit unsigned integer, use
+ * following equation. Edit for v2.6.4
+ */
+ /* Fref_TF = Fref_TG * 1000 */
+ Fref_TG = (state->Fxtal/1000) / MXL_Ceiling(state->Fxtal, 1000000);
+
+ /* Fvco = Fvco/10 */
+ Fvco = (state->TG_LO/10000) * divider_val * Fref_TG;
+
+ tg_lo = (((Fmax/10 - Fvco)/100)*32) / ((Fmax-Fmin)/1000)+8;
+
+ /* below equation is same as above but much harder to debug.
+ * tg_lo = ( ((Fmax/10000 * Xtal_Int)/100) -
+ * ((state->TG_LO/10000)*divider_val *
+ * (state->Fxtal/10000)/100) )*32/((Fmax-Fmin)/10000 *
+ * Xtal_Int/100) + 8;
+ */
+
+ status += MXL_ControlWrite(fe, TG_VCO_BIAS , tg_lo);
+
+ /* add for 2.6.5 Special setting for QAM */
+ if (state->Mod_Type == MXL_QAM) {
+ if (state->RF_IN < 680000000)
+ status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
+ else
+ status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2);
+ }
+
+ /* Off Chip Tracking Filter Control */
+ if (state->TF_Type == MXL_TF_OFF) {
+ /* Tracking Filter Off State; turn off all the banks */
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 3, 1); /* Bank1 Off */
+ status += MXL_SetGPIO(fe, 1, 1); /* Bank2 Off */
+ status += MXL_SetGPIO(fe, 4, 1); /* Bank3 Off */
+ }
+
+ if (state->TF_Type == MXL_TF_C) /* Tracking Filter type C */ {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+ status += MXL_ControlWrite(fe, DAC_DIN_A, 0);
+
+ if (state->RF_IN >= 43000000 && state->RF_IN < 150000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+ status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+ status += MXL_SetGPIO(fe, 3, 0);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ }
+ if (state->RF_IN >= 150000000 && state->RF_IN < 280000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+ status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ }
+ if (state->RF_IN >= 280000000 && state->RF_IN < 360000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+ status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 4, 0);
+ }
+ if (state->RF_IN >= 360000000 && state->RF_IN < 560000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+ status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 4, 0);
+ }
+ if (state->RF_IN >= 560000000 && state->RF_IN < 580000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+ status += MXL_ControlWrite(fe, DAC_DIN_B, 29);
+ status += MXL_SetGPIO(fe, 3, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 4, 0);
+ }
+ if (state->RF_IN >= 580000000 && state->RF_IN < 630000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+ status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 4, 0);
+ }
+ if (state->RF_IN >= 630000000 && state->RF_IN < 700000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+ status += MXL_ControlWrite(fe, DAC_DIN_B, 16);
+ status += MXL_SetGPIO(fe, 3, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ }
+ if (state->RF_IN >= 700000000 && state->RF_IN < 760000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+ status += MXL_ControlWrite(fe, DAC_DIN_B, 7);
+ status += MXL_SetGPIO(fe, 3, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ }
+ if (state->RF_IN >= 760000000 && state->RF_IN <= 900000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+ status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ }
+ }
+
+ if (state->TF_Type == MXL_TF_C_H) {
+
+ /* Tracking Filter type C-H for Hauppauge only */
+ status += MXL_ControlWrite(fe, DAC_DIN_A, 0);
+
+ if (state->RF_IN >= 43000000 && state->RF_IN < 150000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ }
+ if (state->RF_IN >= 150000000 && state->RF_IN < 280000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 3, 0);
+ status += MXL_SetGPIO(fe, 1, 1);
+ }
+ if (state->RF_IN >= 280000000 && state->RF_IN < 360000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 3, 0);
+ status += MXL_SetGPIO(fe, 1, 0);
+ }
+ if (state->RF_IN >= 360000000 && state->RF_IN < 560000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ }
+ if (state->RF_IN >= 560000000 && state->RF_IN < 580000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ }
+ if (state->RF_IN >= 580000000 && state->RF_IN < 630000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ }
+ if (state->RF_IN >= 630000000 && state->RF_IN < 700000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ }
+ if (state->RF_IN >= 700000000 && state->RF_IN < 760000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ }
+ if (state->RF_IN >= 760000000 && state->RF_IN <= 900000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ }
+ }
+
+ if (state->TF_Type == MXL_TF_D) { /* Tracking Filter type D */
+
+ status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+
+ if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 0);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 0);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 250000000 && state->RF_IN < 310000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 310000000 && state->RF_IN < 360000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 360000000 && state->RF_IN < 470000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 470000000 && state->RF_IN < 640000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 640000000 && state->RF_IN <= 900000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ }
+
+ if (state->TF_Type == MXL_TF_D_L) {
+
+ /* Tracking Filter type D-L for Lumanate ONLY change 2.6.3 */
+ status += MXL_ControlWrite(fe, DAC_DIN_A, 0);
+
+ /* if UHF and terrestrial => Turn off Tracking Filter */
+ if (state->RF_IN >= 471000000 &&
+ (state->RF_IN - 471000000)%6000000 != 0) {
+ /* Turn off all the banks */
+ status += MXL_SetGPIO(fe, 3, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+ status += MXL_ControlWrite(fe, AGC_IF, 10);
+ } else {
+ /* if VHF or cable => Turn on Tracking Filter */
+ if (state->RF_IN >= 43000000 &&
+ state->RF_IN < 140000000) {
+
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 140000000 &&
+ state->RF_IN < 240000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 240000000 &&
+ state->RF_IN < 340000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 0);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 340000000 &&
+ state->RF_IN < 430000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 0);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 430000000 &&
+ state->RF_IN < 470000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 470000000 &&
+ state->RF_IN < 570000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 0);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 570000000 &&
+ state->RF_IN < 620000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 0);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 620000000 &&
+ state->RF_IN < 760000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 0);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 760000000 &&
+ state->RF_IN <= 900000000) {
+ status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ }
+ }
+
+ if (state->TF_Type == MXL_TF_E) /* Tracking Filter type E */ {
+
+ status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+
+ if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 0);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 0);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 250000000 && state->RF_IN < 310000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 310000000 && state->RF_IN < 360000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 360000000 && state->RF_IN < 470000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 470000000 && state->RF_IN < 640000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 640000000 && state->RF_IN <= 900000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ }
+
+ if (state->TF_Type == MXL_TF_F) {
+
+ /* Tracking Filter type F */
+ status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+
+ if (state->RF_IN >= 43000000 && state->RF_IN < 160000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 0);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 160000000 && state->RF_IN < 210000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 0);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 210000000 && state->RF_IN < 300000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 300000000 && state->RF_IN < 390000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 390000000 && state->RF_IN < 515000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 515000000 && state->RF_IN < 650000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 650000000 && state->RF_IN <= 900000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ }
+
+ if (state->TF_Type == MXL_TF_E_2) {
+
+ /* Tracking Filter type E_2 */
+ status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+
+ if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 0);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 0);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 250000000 && state->RF_IN < 350000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 350000000 && state->RF_IN < 400000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 400000000 && state->RF_IN < 570000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 570000000 && state->RF_IN < 770000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 770000000 && state->RF_IN <= 900000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ }
+
+ if (state->TF_Type == MXL_TF_G) {
+
+ /* Tracking Filter type G add for v2.6.8 */
+ status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+
+ if (state->RF_IN >= 50000000 && state->RF_IN < 190000000) {
+
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 0);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 190000000 && state->RF_IN < 280000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 0);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 280000000 && state->RF_IN < 350000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 350000000 && state->RF_IN < 400000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 400000000 && state->RF_IN < 470000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 470000000 && state->RF_IN < 640000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 640000000 && state->RF_IN < 820000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 820000000 && state->RF_IN <= 900000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ }
+
+ if (state->TF_Type == MXL_TF_E_NA) {
+
+ /* Tracking Filter type E-NA for Empia ONLY change for 2.6.8 */
+ status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
+
+ /* if UHF and terrestrial=> Turn off Tracking Filter */
+ if (state->RF_IN >= 471000000 &&
+ (state->RF_IN - 471000000)%6000000 != 0) {
+
+ /* Turn off all the banks */
+ status += MXL_SetGPIO(fe, 3, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+
+ /* 2.6.12 Turn on RSSI */
+ status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
+ status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
+ status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
+ status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
+
+ /* RSSI reference point */
+ status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
+ status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
+ status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 2);
+
+ /* following parameter is from analog OTA mode,
+ * can be change to seek better performance */
+ status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
+ } else {
+ /* if VHF or Cable => Turn on Tracking Filter */
+
+ /* 2.6.12 Turn off RSSI */
+ status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
+
+ /* change back from above condition */
+ status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 5);
+
+
+ if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
+
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 0);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 0);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 250000000 && state->RF_IN < 350000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ if (state->RF_IN >= 350000000 && state->RF_IN < 400000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 0);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 400000000 && state->RF_IN < 570000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 570000000 && state->RF_IN < 770000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 0);
+ }
+ if (state->RF_IN >= 770000000 && state->RF_IN <= 900000000) {
+ status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
+ status += MXL_SetGPIO(fe, 4, 1);
+ status += MXL_SetGPIO(fe, 1, 1);
+ status += MXL_SetGPIO(fe, 3, 1);
+ }
+ }
+ }
+ return status ;
+}
+
+static u16 MXL_SetGPIO(struct dvb_frontend *fe, u8 GPIO_Num, u8 GPIO_Val)
+{
+ u16 status = 0;
+
+ if (GPIO_Num == 1)
+ status += MXL_ControlWrite(fe, GPIO_1B, GPIO_Val ? 0 : 1);
+
+ /* GPIO2 is not available */
+
+ if (GPIO_Num == 3) {
+ if (GPIO_Val == 1) {
+ status += MXL_ControlWrite(fe, GPIO_3, 0);
+ status += MXL_ControlWrite(fe, GPIO_3B, 0);
+ }
+ if (GPIO_Val == 0) {
+ status += MXL_ControlWrite(fe, GPIO_3, 1);
+ status += MXL_ControlWrite(fe, GPIO_3B, 1);
+ }
+ if (GPIO_Val == 3) { /* tri-state */
+ status += MXL_ControlWrite(fe, GPIO_3, 0);
+ status += MXL_ControlWrite(fe, GPIO_3B, 1);
+ }
+ }
+ if (GPIO_Num == 4) {
+ if (GPIO_Val == 1) {
+ status += MXL_ControlWrite(fe, GPIO_4, 0);
+ status += MXL_ControlWrite(fe, GPIO_4B, 0);
+ }
+ if (GPIO_Val == 0) {
+ status += MXL_ControlWrite(fe, GPIO_4, 1);
+ status += MXL_ControlWrite(fe, GPIO_4B, 1);
+ }
+ if (GPIO_Val == 3) { /* tri-state */
+ status += MXL_ControlWrite(fe, GPIO_4, 0);
+ status += MXL_ControlWrite(fe, GPIO_4B, 1);
+ }
+ }
+
+ return status;
+}
+
+static u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value)
+{
+ u16 status = 0;
+
+ /* Will write ALL Matching Control Name */
+ /* Write Matching INIT Control */
+ status += MXL_ControlWrite_Group(fe, ControlNum, value, 1);
+ /* Write Matching CH Control */
+ status += MXL_ControlWrite_Group(fe, ControlNum, value, 2);
+#ifdef _MXL_INTERNAL
+ /* Write Matching MXL Control */
+ status += MXL_ControlWrite_Group(fe, ControlNum, value, 3);
+#endif
+ return status;
+}
+
+static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum,
+ u32 value, u16 controlGroup)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ u16 i, j, k;
+ u32 highLimit;
+ u32 ctrlVal;
+
+ if (controlGroup == 1) /* Initial Control */ {
+
+ for (i = 0; i < state->Init_Ctrl_Num; i++) {
+
+ if (controlNum == state->Init_Ctrl[i].Ctrl_Num) {
+
+ highLimit = 1 << state->Init_Ctrl[i].size;
+ if (value < highLimit) {
+ for (j = 0; j < state->Init_Ctrl[i].size; j++) {
+ state->Init_Ctrl[i].val[j] = (u8)((value >> j) & 0x01);
+ MXL_RegWriteBit(fe, (u8)(state->Init_Ctrl[i].addr[j]),
+ (u8)(state->Init_Ctrl[i].bit[j]),
+ (u8)((value>>j) & 0x01));
+ }
+ ctrlVal = 0;
+ for (k = 0; k < state->Init_Ctrl[i].size; k++)
+ ctrlVal += state->Init_Ctrl[i].val[k] * (1 << k);
+ } else
+ return -1;
+ }
+ }
+ }
+ if (controlGroup == 2) /* Chan change Control */ {
+
+ for (i = 0; i < state->CH_Ctrl_Num; i++) {
+
+ if (controlNum == state->CH_Ctrl[i].Ctrl_Num) {
+
+ highLimit = 1 << state->CH_Ctrl[i].size;
+ if (value < highLimit) {
+ for (j = 0; j < state->CH_Ctrl[i].size; j++) {
+ state->CH_Ctrl[i].val[j] = (u8)((value >> j) & 0x01);
+ MXL_RegWriteBit(fe, (u8)(state->CH_Ctrl[i].addr[j]),
+ (u8)(state->CH_Ctrl[i].bit[j]),
+ (u8)((value>>j) & 0x01));
+ }
+ ctrlVal = 0;
+ for (k = 0; k < state->CH_Ctrl[i].size; k++)
+ ctrlVal += state->CH_Ctrl[i].val[k] * (1 << k);
+ } else
+ return -1;
+ }
+ }
+ }
+#ifdef _MXL_INTERNAL
+ if (controlGroup == 3) /* Maxlinear Control */ {
+
+ for (i = 0; i < state->MXL_Ctrl_Num; i++) {
+
+ if (controlNum == state->MXL_Ctrl[i].Ctrl_Num) {
+
+ highLimit = (1 << state->MXL_Ctrl[i].size);
+ if (value < highLimit) {
+ for (j = 0; j < state->MXL_Ctrl[i].size; j++) {
+ state->MXL_Ctrl[i].val[j] = (u8)((value >> j) & 0x01);
+ MXL_RegWriteBit(fe, (u8)(state->MXL_Ctrl[i].addr[j]),
+ (u8)(state->MXL_Ctrl[i].bit[j]),
+ (u8)((value>>j) & 0x01));
+ }
+ ctrlVal = 0;
+ for (k = 0; k < state->MXL_Ctrl[i].size; k++)
+ ctrlVal += state->MXL_Ctrl[i].val[k] * (1 << k);
+ } else
+ return -1;
+ }
+ }
+ }
+#endif
+ return 0 ; /* successful return */
+}
+
+static u16 MXL_RegRead(struct dvb_frontend *fe, u8 RegNum, u8 *RegVal)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ int i ;
+
+ for (i = 0; i < 104; i++) {
+ if (RegNum == state->TunerRegs[i].Reg_Num) {
+ *RegVal = (u8)(state->TunerRegs[i].Reg_Val);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ u32 ctrlVal ;
+ u16 i, k ;
+
+ for (i = 0; i < state->Init_Ctrl_Num ; i++) {
+
+ if (controlNum == state->Init_Ctrl[i].Ctrl_Num) {
+
+ ctrlVal = 0;
+ for (k = 0; k < state->Init_Ctrl[i].size; k++)
+ ctrlVal += state->Init_Ctrl[i].val[k] * (1<<k);
+ *value = ctrlVal;
+ return 0;
+ }
+ }
+
+ for (i = 0; i < state->CH_Ctrl_Num ; i++) {
+
+ if (controlNum == state->CH_Ctrl[i].Ctrl_Num) {
+
+ ctrlVal = 0;
+ for (k = 0; k < state->CH_Ctrl[i].size; k++)
+ ctrlVal += state->CH_Ctrl[i].val[k] * (1 << k);
+ *value = ctrlVal;
+ return 0;
+
+ }
+ }
+
+#ifdef _MXL_INTERNAL
+ for (i = 0; i < state->MXL_Ctrl_Num ; i++) {
+
+ if (controlNum == state->MXL_Ctrl[i].Ctrl_Num) {
+
+ ctrlVal = 0;
+ for (k = 0; k < state->MXL_Ctrl[i].size; k++)
+ ctrlVal += state->MXL_Ctrl[i].val[k] * (1<<k);
+ *value = ctrlVal;
+ return 0;
+
+ }
+ }
+#endif
+ return 1;
+}
+
+static void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit,
+ u8 bitVal)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ int i ;
+
+ const u8 AND_MAP[8] = {
+ 0xFE, 0xFD, 0xFB, 0xF7,
+ 0xEF, 0xDF, 0xBF, 0x7F } ;
+
+ const u8 OR_MAP[8] = {
+ 0x01, 0x02, 0x04, 0x08,
+ 0x10, 0x20, 0x40, 0x80 } ;
+
+ for (i = 0; i < state->TunerRegs_Num; i++) {
+ if (state->TunerRegs[i].Reg_Num == address) {
+ if (bitVal)
+ state->TunerRegs[i].Reg_Val |= OR_MAP[bit];
+ else
+ state->TunerRegs[i].Reg_Val &= AND_MAP[bit];
+ break ;
+ }
+ }
+}
+
+static u32 MXL_Ceiling(u32 value, u32 resolution)
+{
+ return (value/resolution + (value % resolution > 0 ? 1 : 0));
+}
+
+/* Retrieve the Initialzation Registers */
+static u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 *RegNum,
+ u8 *RegVal, int *count)
+{
+ u16 status = 0;
+ int i ;
+
+ u8 RegAddr[] = {
+ 11, 12, 13, 22, 32, 43, 44, 53, 56, 59, 73,
+ 76, 77, 91, 134, 135, 137, 147,
+ 156, 166, 167, 168, 25 };
+
+ *count = sizeof(RegAddr) / sizeof(u8);
+
+ status += MXL_BlockInit(fe);
+
+ for (i = 0 ; i < *count; i++) {
+ RegNum[i] = RegAddr[i];
+ status += MXL_RegRead(fe, RegNum[i], &RegVal[i]);
+ }
+
+ return status;
+}
+
+static u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 *RegNum, u8 *RegVal,
+ int *count)
+{
+ u16 status = 0;
+ int i ;
+
+/* add 77, 166, 167, 168 register for 2.6.12 */
+#ifdef _MXL_PRODUCTION
+ u8 RegAddr[] = {14, 15, 16, 17, 22, 43, 65, 68, 69, 70, 73, 92, 93, 106,
+ 107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168 } ;
+#else
+ u8 RegAddr[] = {14, 15, 16, 17, 22, 43, 68, 69, 70, 73, 92, 93, 106,
+ 107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168 } ;
+ /*
+ u8 RegAddr[171];
+ for (i = 0; i <= 170; i++)
+ RegAddr[i] = i;
+ */
+#endif
+
+ *count = sizeof(RegAddr) / sizeof(u8);
+
+ for (i = 0 ; i < *count; i++) {
+ RegNum[i] = RegAddr[i];
+ status += MXL_RegRead(fe, RegNum[i], &RegVal[i]);
+ }
+
+ return status;
+}
+
+static u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 *RegNum,
+ u8 *RegVal, int *count)
+{
+ u16 status = 0;
+ int i;
+
+ u8 RegAddr[] = {43, 136};
+
+ *count = sizeof(RegAddr) / sizeof(u8);
+
+ for (i = 0; i < *count; i++) {
+ RegNum[i] = RegAddr[i];
+ status += MXL_RegRead(fe, RegNum[i], &RegVal[i]);
+ }
+
+ return status;
+}
+
+static u16 MXL_GetMasterControl(u8 *MasterReg, int state)
+{
+ if (state == 1) /* Load_Start */
+ *MasterReg = 0xF3;
+ if (state == 2) /* Power_Down */
+ *MasterReg = 0x41;
+ if (state == 3) /* Synth_Reset */
+ *MasterReg = 0xB1;
+ if (state == 4) /* Seq_Off */
+ *MasterReg = 0xF1;
+
+ return 0;
+}
+
+#ifdef _MXL_PRODUCTION
+static u16 MXL_VCORange_Test(struct dvb_frontend *fe, int VCO_Range)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ u16 status = 0 ;
+
+ if (VCO_Range == 1) {
+ status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
+ status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+ status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
+ status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+ status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
+ if (state->Mode == 0 && state->IF_Mode == 1) {
+ /* Analog Low IF Mode */
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+ status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+ status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 56);
+ status += MXL_ControlWrite(fe,
+ CHCAL_FRAC_MOD_RF, 180224);
+ }
+ if (state->Mode == 0 && state->IF_Mode == 0) {
+ /* Analog Zero IF Mode */
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+ status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+ status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 56);
+ status += MXL_ControlWrite(fe,
+ CHCAL_FRAC_MOD_RF, 222822);
+ }
+ if (state->Mode == 1) /* Digital Mode */ {
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+ status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+ status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 56);
+ status += MXL_ControlWrite(fe,
+ CHCAL_FRAC_MOD_RF, 229376);
+ }
+ }
+
+ if (VCO_Range == 2) {
+ status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
+ status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+ status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
+ status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+ status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+ status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+ status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 41);
+ if (state->Mode == 0 && state->IF_Mode == 1) {
+ /* Analog Low IF Mode */
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+ status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+ status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
+ status += MXL_ControlWrite(fe,
+ CHCAL_FRAC_MOD_RF, 206438);
+ }
+ if (state->Mode == 0 && state->IF_Mode == 0) {
+ /* Analog Zero IF Mode */
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+ status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+ status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
+ status += MXL_ControlWrite(fe,
+ CHCAL_FRAC_MOD_RF, 206438);
+ }
+ if (state->Mode == 1) /* Digital Mode */ {
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
+ status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+ status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 41);
+ status += MXL_ControlWrite(fe,
+ CHCAL_FRAC_MOD_RF, 16384);
+ }
+ }
+
+ if (VCO_Range == 3) {
+ status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
+ status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+ status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
+ status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+ status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+ status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+ status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
+ if (state->Mode == 0 && state->IF_Mode == 1) {
+ /* Analog Low IF Mode */
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+ status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+ status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 44);
+ status += MXL_ControlWrite(fe,
+ CHCAL_FRAC_MOD_RF, 173670);
+ }
+ if (state->Mode == 0 && state->IF_Mode == 0) {
+ /* Analog Zero IF Mode */
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+ status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+ status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 44);
+ status += MXL_ControlWrite(fe,
+ CHCAL_FRAC_MOD_RF, 173670);
+ }
+ if (state->Mode == 1) /* Digital Mode */ {
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+ status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
+ status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
+ status += MXL_ControlWrite(fe,
+ CHCAL_FRAC_MOD_RF, 245760);
+ }
+ }
+
+ if (VCO_Range == 4) {
+ status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
+ status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
+ status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
+ status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
+ status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+ status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+ status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
+ if (state->Mode == 0 && state->IF_Mode == 1) {
+ /* Analog Low IF Mode */
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+ status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+ status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
+ status += MXL_ControlWrite(fe,
+ CHCAL_FRAC_MOD_RF, 206438);
+ }
+ if (state->Mode == 0 && state->IF_Mode == 0) {
+ /* Analog Zero IF Mode */
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+ status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+ status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
+ status += MXL_ControlWrite(fe,
+ CHCAL_FRAC_MOD_RF, 206438);
+ }
+ if (state->Mode == 1) /* Digital Mode */ {
+ status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
+ status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
+ status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
+ status += MXL_ControlWrite(fe,
+ CHCAL_FRAC_MOD_RF, 212992);
+ }
+ }
+
+ return status;
+}
+
+static u16 MXL_Hystersis_Test(struct dvb_frontend *fe, int Hystersis)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ u16 status = 0;
+
+ if (Hystersis == 1)
+ status += MXL_ControlWrite(fe, DN_BYPASS_AGC_I2C, 1);
+
+ return status;
+}
+#endif
+/* End: Reference driver code found in the Realtek driver that
+ * is copyright MaxLinear */
+
+/* ----------------------------------------------------------------
+ * Begin: Everything after here is new code to adapt the
+ * proprietary Realtek driver into a Linux API tuner.
+ * Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+ */
+static int mxl5005s_reset(struct dvb_frontend *fe)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ int ret = 0;
+
+ u8 buf[2] = { 0xff, 0x00 };
+ struct i2c_msg msg = { .addr = state->config->i2c_address, .flags = 0,
+ .buf = buf, .len = 2 };
+
+ dprintk(2, "%s()\n", __func__);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+ printk(KERN_WARNING "mxl5005s I2C reset failed\n");
+ ret = -EREMOTEIO;
+ }
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return ret;
+}
+
+/* Write a single byte to a single reg, latch the value if required by
+ * following the transaction with the latch byte.
+ */
+static int mxl5005s_writereg(struct dvb_frontend *fe, u8 reg, u8 val, int latch)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ u8 buf[3] = { reg, val, MXL5005S_LATCH_BYTE };
+ struct i2c_msg msg = { .addr = state->config->i2c_address, .flags = 0,
+ .buf = buf, .len = 3 };
+
+ if (latch == 0)
+ msg.len = 2;
+
+ dprintk(2, "%s(0x%x, 0x%x, 0x%x)\n", __func__, reg, val, msg.addr);
+
+ if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+ printk(KERN_WARNING "mxl5005s I2C write failed\n");
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+static int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable,
+ u8 *datatable, u8 len)
+{
+ int ret = 0, i;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ for (i = 0 ; i < len-1; i++) {
+ ret = mxl5005s_writereg(fe, addrtable[i], datatable[i], 0);
+ if (ret < 0)
+ break;
+ }
+
+ ret = mxl5005s_writereg(fe, addrtable[i], datatable[i], 1);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return ret;
+}
+
+static int mxl5005s_init(struct dvb_frontend *fe)
+{
+ dprintk(1, "%s()\n", __func__);
+ return mxl5005s_reconfigure(fe, MXL_QAM, MXL5005S_BANDWIDTH_6MHZ);
+}
+
+static int mxl5005s_reconfigure(struct dvb_frontend *fe, u32 mod_type,
+ u32 bandwidth)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+
+ u8 AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
+ u8 ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
+ int TableLen;
+
+ dprintk(1, "%s(type=%d, bw=%d)\n", __func__, mod_type, bandwidth);
+
+ mxl5005s_reset(fe);
+
+ /* Tuner initialization stage 0 */
+ MXL_GetMasterControl(ByteTable, MC_SYNTH_RESET);
+ AddrTable[0] = MASTER_CONTROL_ADDR;
+ ByteTable[0] |= state->config->AgcMasterByte;
+
+ mxl5005s_writeregs(fe, AddrTable, ByteTable, 1);
+
+ mxl5005s_AssignTunerMode(fe, mod_type, bandwidth);
+
+ /* Tuner initialization stage 1 */
+ MXL_GetInitRegister(fe, AddrTable, ByteTable, &TableLen);
+
+ mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen);
+
+ return 0;
+}
+
+static int mxl5005s_AssignTunerMode(struct dvb_frontend *fe, u32 mod_type,
+ u32 bandwidth)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ struct mxl5005s_config *c = state->config;
+
+ InitTunerControls(fe);
+
+ /* Set MxL5005S parameters. */
+ MXL5005_TunerConfig(
+ fe,
+ c->mod_mode,
+ c->if_mode,
+ bandwidth,
+ c->if_freq,
+ c->xtal_freq,
+ c->agc_mode,
+ c->top,
+ c->output_load,
+ c->clock_out,
+ c->div_out,
+ c->cap_select,
+ c->rssi_enable,
+ mod_type,
+ c->tracking_filter);
+
+ return 0;
+}
+
+static int mxl5005s_set_params(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ u32 req_mode, req_bw = 0;
+ int ret;
+
+ dprintk(1, "%s()\n", __func__);
+
+ if (fe->ops.info.type == FE_ATSC) {
+ switch (params->u.vsb.modulation) {
+ case VSB_8:
+ req_mode = MXL_ATSC; break;
+ default:
+ case QAM_64:
+ case QAM_256:
+ case QAM_AUTO:
+ req_mode = MXL_QAM; break;
+ }
+ } else
+ req_mode = MXL_DVBT;
+
+ /* Change tuner for new modulation type if reqd */
+ if (req_mode != state->current_mode) {
+ switch (req_mode) {
+ case VSB_8:
+ case QAM_64:
+ case QAM_256:
+ case QAM_AUTO:
+ req_bw = MXL5005S_BANDWIDTH_6MHZ;
+ break;
+ default:
+ /* Assume DVB-T */
+ switch (params->u.ofdm.bandwidth) {
+ case BANDWIDTH_6_MHZ:
+ req_bw = MXL5005S_BANDWIDTH_6MHZ;
+ break;
+ case BANDWIDTH_7_MHZ:
+ req_bw = MXL5005S_BANDWIDTH_7MHZ;
+ break;
+ case BANDWIDTH_AUTO:
+ case BANDWIDTH_8_MHZ:
+ req_bw = MXL5005S_BANDWIDTH_8MHZ;
+ break;
+ }
+ }
+
+ state->current_mode = req_mode;
+ ret = mxl5005s_reconfigure(fe, req_mode, req_bw);
+
+ } else
+ ret = 0;
+
+ if (ret == 0) {
+ dprintk(1, "%s() freq=%d\n", __func__, params->frequency);
+ ret = mxl5005s_SetRfFreqHz(fe, params->frequency);
+ }
+
+ return ret;
+}
+
+static int mxl5005s_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ dprintk(1, "%s()\n", __func__);
+
+ *frequency = state->RF_IN;
+
+ return 0;
+}
+
+static int mxl5005s_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+ struct mxl5005s_state *state = fe->tuner_priv;
+ dprintk(1, "%s()\n", __func__);
+
+ *bandwidth = state->Chan_Bandwidth;
+
+ return 0;
+}
+
+static int mxl5005s_release(struct dvb_frontend *fe)
+{
+ dprintk(1, "%s()\n", __func__);
+ kfree(fe->tuner_priv);
+ fe->tuner_priv = NULL;
+ return 0;
+}
+
+static const struct dvb_tuner_ops mxl5005s_tuner_ops = {
+ .info = {
+ .name = "MaxLinear MXL5005S",
+ .frequency_min = 48000000,
+ .frequency_max = 860000000,
+ .frequency_step = 50000,
+ },
+
+ .release = mxl5005s_release,
+ .init = mxl5005s_init,
+
+ .set_params = mxl5005s_set_params,
+ .get_frequency = mxl5005s_get_frequency,
+ .get_bandwidth = mxl5005s_get_bandwidth,
+};
+
+struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c,
+ struct mxl5005s_config *config)
+{
+ struct mxl5005s_state *state = NULL;
+ dprintk(1, "%s()\n", __func__);
+
+ state = kzalloc(sizeof(struct mxl5005s_state), GFP_KERNEL);
+ if (state == NULL)
+ return NULL;
+
+ state->frontend = fe;
+ state->config = config;
+ state->i2c = i2c;
+ state->current_mode = MXL_QAM;
+
+ printk(KERN_INFO "MXL5005S: Attached at address 0x%02x\n",
+ config->i2c_address);
+
+ memcpy(&fe->ops.tuner_ops, &mxl5005s_tuner_ops,
+ sizeof(struct dvb_tuner_ops));
+
+ fe->tuner_priv = state;
+ return fe;
+}
+EXPORT_SYMBOL(mxl5005s_attach);
+
+MODULE_DESCRIPTION("MaxLinear MXL5005S silicon tuner driver");
+MODULE_AUTHOR("Steven Toth");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/mxl5005s.h b/drivers/media/common/tuners/mxl5005s.h
new file mode 100644
index 0000000..396db15
--- /dev/null
+++ b/drivers/media/common/tuners/mxl5005s.h
@@ -0,0 +1,131 @@
+/*
+ MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
+
+ Copyright (C) 2008 MaxLinear
+ Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __MXL5005S_H
+#define __MXL5005S_H
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+struct mxl5005s_config {
+
+ /* 7 bit i2c address */
+ u8 i2c_address;
+
+#define IF_FREQ_4570000HZ 4570000
+#define IF_FREQ_4571429HZ 4571429
+#define IF_FREQ_5380000HZ 5380000
+#define IF_FREQ_36000000HZ 36000000
+#define IF_FREQ_36125000HZ 36125000
+#define IF_FREQ_36166667HZ 36166667
+#define IF_FREQ_44000000HZ 44000000
+ u32 if_freq;
+
+#define CRYSTAL_FREQ_4000000HZ 4000000
+#define CRYSTAL_FREQ_16000000HZ 16000000
+#define CRYSTAL_FREQ_25000000HZ 25000000
+#define CRYSTAL_FREQ_28800000HZ 28800000
+ u32 xtal_freq;
+
+#define MXL_DUAL_AGC 0
+#define MXL_SINGLE_AGC 1
+ u8 agc_mode;
+
+#define MXL_TF_DEFAULT 0
+#define MXL_TF_OFF 1
+#define MXL_TF_C 2
+#define MXL_TF_C_H 3
+#define MXL_TF_D 4
+#define MXL_TF_D_L 5
+#define MXL_TF_E 6
+#define MXL_TF_F 7
+#define MXL_TF_E_2 8
+#define MXL_TF_E_NA 9
+#define MXL_TF_G 10
+ u8 tracking_filter;
+
+#define MXL_RSSI_DISABLE 0
+#define MXL_RSSI_ENABLE 1
+ u8 rssi_enable;
+
+#define MXL_CAP_SEL_DISABLE 0
+#define MXL_CAP_SEL_ENABLE 1
+ u8 cap_select;
+
+#define MXL_DIV_OUT_1 0
+#define MXL_DIV_OUT_4 1
+ u8 div_out;
+
+#define MXL_CLOCK_OUT_DISABLE 0
+#define MXL_CLOCK_OUT_ENABLE 1
+ u8 clock_out;
+
+#define MXL5005S_IF_OUTPUT_LOAD_200_OHM 200
+#define MXL5005S_IF_OUTPUT_LOAD_300_OHM 300
+ u32 output_load;
+
+#define MXL5005S_TOP_5P5 55
+#define MXL5005S_TOP_7P2 72
+#define MXL5005S_TOP_9P2 92
+#define MXL5005S_TOP_11P0 110
+#define MXL5005S_TOP_12P9 129
+#define MXL5005S_TOP_14P7 147
+#define MXL5005S_TOP_16P8 168
+#define MXL5005S_TOP_19P4 194
+#define MXL5005S_TOP_21P2 212
+#define MXL5005S_TOP_23P2 232
+#define MXL5005S_TOP_25P2 252
+#define MXL5005S_TOP_27P1 271
+#define MXL5005S_TOP_29P2 292
+#define MXL5005S_TOP_31P7 317
+#define MXL5005S_TOP_34P9 349
+ u32 top;
+
+#define MXL_ANALOG_MODE 0
+#define MXL_DIGITAL_MODE 1
+ u8 mod_mode;
+
+#define MXL_ZERO_IF 0
+#define MXL_LOW_IF 1
+ u8 if_mode;
+
+ /* Stuff I don't know what to do with */
+ u8 AgcMasterByte;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_MXL5005S) || \
+ (defined(CONFIG_MEDIA_TUNER_MXL5005S_MODULE) && defined(MODULE))
+extern struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c,
+ struct mxl5005s_config *config);
+#else
+static inline struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c,
+ struct mxl5005s_config *config)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_DVB_TUNER_MXL5005S */
+
+#endif /* __MXL5005S_H */
+
diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c
index e27a762..42b5f5d 100644
--- a/drivers/media/common/tuners/tda18271-common.c
+++ b/drivers/media/common/tuners/tda18271-common.c
@@ -227,9 +227,8 @@
regs[r_cp] &= ~0x20;
regs[r_cp] |= ((force & 1) << 5);
- tda18271_write_regs(fe, r_cp, 1);
- return 0;
+ return tda18271_write_regs(fe, r_cp, 1);
}
int tda18271_init_regs(struct dvb_frontend *fe)
@@ -487,16 +486,15 @@
struct tda18271_priv *priv = fe->tuner_priv;
unsigned char *regs = priv->tda18271_regs;
- tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt);
+ if (tda18271_debug & DBG_ADV)
+ tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt);
regs[R_EP3] &= ~0xe0; /* clear sm, sm_lt, sm_xt */
regs[R_EP3] |= sm ? (1 << 7) : 0 |
sm_lt ? (1 << 6) : 0 |
sm_xt ? (1 << 5) : 0;
- tda18271_write_regs(fe, R_EP3, 1);
-
- return 0;
+ return tda18271_write_regs(fe, R_EP3, 1);
}
/*---------------------------------------------------------------------*/
@@ -510,7 +508,7 @@
u32 div;
int ret = tda18271_lookup_pll_map(fe, MAIN_PLL, &freq, &pd, &d);
- if (ret < 0)
+ if (tda_fail(ret))
goto fail;
regs[R_MPD] = (0x77 & pd);
@@ -542,7 +540,7 @@
u32 div;
int ret = tda18271_lookup_pll_map(fe, CAL_PLL, &freq, &pd, &d);
- if (ret < 0)
+ if (tda_fail(ret))
goto fail;
regs[R_CPD] = pd;
@@ -566,7 +564,7 @@
u8 val;
int ret = tda18271_lookup_map(fe, BP_FILTER, freq, &val);
- if (ret < 0)
+ if (tda_fail(ret))
goto fail;
regs[R_EP1] &= ~0x07; /* clear bp filter bits */
@@ -583,7 +581,7 @@
u8 val;
int ret = tda18271_lookup_map(fe, RF_CAL_KMCO, freq, &val);
- if (ret < 0)
+ if (tda_fail(ret))
goto fail;
regs[R_EB13] &= ~0x7c; /* clear k & m bits */
@@ -600,7 +598,7 @@
u8 val;
int ret = tda18271_lookup_map(fe, RF_BAND, freq, &val);
- if (ret < 0)
+ if (tda_fail(ret))
goto fail;
regs[R_EP2] &= ~0xe0; /* clear rf band bits */
@@ -617,7 +615,7 @@
u8 val;
int ret = tda18271_lookup_map(fe, GAIN_TAPER, freq, &val);
- if (ret < 0)
+ if (tda_fail(ret))
goto fail;
regs[R_EP2] &= ~0x1f; /* clear gain taper bits */
@@ -634,7 +632,7 @@
u8 val;
int ret = tda18271_lookup_map(fe, IR_MEASURE, freq, &val);
- if (ret < 0)
+ if (tda_fail(ret))
goto fail;
regs[R_EP5] &= ~0x07;
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
index b262100..89c01fb 100644
--- a/drivers/media/common/tuners/tda18271-fe.c
+++ b/drivers/media/common/tuners/tda18271-fe.c
@@ -51,6 +51,7 @@
{
struct tda18271_priv *priv = fe->tuner_priv;
unsigned char *regs = priv->tda18271_regs;
+ int ret;
u32 N;
/* update TV broadcast parameters */
@@ -85,7 +86,9 @@
/* update rf top / if top */
regs[R_EB22] = 0x00;
regs[R_EB22] |= map->rfagc_top;
- tda18271_write_regs(fe, R_EB22, 1);
+ ret = tda18271_write_regs(fe, R_EB22, 1);
+ if (tda_fail(ret))
+ goto fail;
/* --------------------------------------------------------------- */
@@ -121,7 +124,9 @@
/* agc1 has priority on agc2 */
regs[R_EB1] &= ~0x01;
- tda18271_write_regs(fe, R_EB1, 1);
+ ret = tda18271_write_regs(fe, R_EB1, 1);
+ if (tda_fail(ret))
+ goto fail;
/* --------------------------------------------------------------- */
@@ -141,7 +146,9 @@
break;
}
- tda18271_write_regs(fe, R_TM, 7);
+ ret = tda18271_write_regs(fe, R_TM, 7);
+ if (tda_fail(ret))
+ goto fail;
/* force charge pump source */
charge_pump_source(fe, 1);
@@ -158,9 +165,9 @@
regs[R_EP3] &= ~0x04;
else
regs[R_EP3] |= 0x04;
- tda18271_write_regs(fe, R_EP3, 1);
-
- return 0;
+ ret = tda18271_write_regs(fe, R_EP3, 1);
+fail:
+ return ret;
}
static int tda18271_read_thermometer(struct dvb_frontend *fe)
@@ -213,11 +220,13 @@
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 tm_current, rfcal_comp, approx, i;
+ int tm_current, rfcal_comp, approx, i, ret;
u8 dc_over_dt, rf_tab;
/* power up */
- tda18271_set_standby_mode(fe, 0, 0, 0);
+ ret = tda18271_set_standby_mode(fe, 0, 0, 0);
+ if (tda_fail(ret))
+ goto fail;
/* read die current temperature */
tm_current = tda18271_read_thermometer(fe);
@@ -228,8 +237,8 @@
rf_tab = regs[R_EB14];
i = tda18271_lookup_rf_band(fe, &freq, NULL);
- if (i < 0)
- return -EINVAL;
+ if (tda_fail(i))
+ return i;
if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) {
approx = map[i].rf_a1 *
@@ -250,35 +259,42 @@
rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal);
regs[R_EB14] = approx + rfcal_comp;
- tda18271_write_regs(fe, R_EB14, 1);
-
- return 0;
+ ret = tda18271_write_regs(fe, R_EB14, 1);
+fail:
+ return ret;
}
static int tda18271_por(struct dvb_frontend *fe)
{
struct tda18271_priv *priv = fe->tuner_priv;
unsigned char *regs = priv->tda18271_regs;
+ int ret;
/* power up detector 1 */
regs[R_EB12] &= ~0x20;
- tda18271_write_regs(fe, R_EB12, 1);
+ ret = tda18271_write_regs(fe, R_EB12, 1);
+ if (tda_fail(ret))
+ goto fail;
regs[R_EB18] &= ~0x80; /* turn agc1 loop on */
regs[R_EB18] &= ~0x03; /* set agc1_gain to 6 dB */
- tda18271_write_regs(fe, R_EB18, 1);
+ ret = tda18271_write_regs(fe, R_EB18, 1);
+ if (tda_fail(ret))
+ goto fail;
regs[R_EB21] |= 0x03; /* set agc2_gain to -6 dB */
/* POR mode */
- tda18271_set_standby_mode(fe, 1, 0, 0);
+ ret = tda18271_set_standby_mode(fe, 1, 0, 0);
+ if (tda_fail(ret))
+ goto fail;
/* disable 1.5 MHz low pass filter */
regs[R_EB23] &= ~0x04; /* forcelp_fc2_en = 0 */
regs[R_EB23] &= ~0x02; /* XXX: lp_fc[2] = 0 */
- tda18271_write_regs(fe, R_EB21, 3);
-
- return 0;
+ ret = tda18271_write_regs(fe, R_EB21, 3);
+fail:
+ return ret;
}
static int tda18271_calibrate_rf(struct dvb_frontend *fe, u32 freq)
@@ -389,7 +405,7 @@
{
struct tda18271_priv *priv = fe->tuner_priv;
unsigned char *regs = priv->tda18271_regs;
- int sgn, bcal, count, wait;
+ int sgn, bcal, count, wait, ret;
u8 cid_target;
u16 count_limit;
u32 freq;
@@ -421,7 +437,9 @@
tda18271_write_regs(fe, R_EP2, 1);
/* read power detection info, stored in EB10 */
- tda18271_read_extended(fe);
+ ret = tda18271_read_extended(fe);
+ if (tda_fail(ret))
+ return ret;
/* algorithm initialization */
sgn = 1;
@@ -447,7 +465,9 @@
tda18271_write_regs(fe, R_EP2, 1);
/* read power detection info, stored in EB10 */
- tda18271_read_extended(fe);
+ ret = tda18271_read_extended(fe);
+ if (tda_fail(ret))
+ return ret;
count += 200;
@@ -478,6 +498,7 @@
{
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 */
@@ -489,10 +510,14 @@
/* update IF output level & IF notch frequency */
regs[R_EP4] &= ~0x1c; /* clear if level bits */
- tda18271_write_regs(fe, R_EP3, 2);
+ ret = tda18271_write_regs(fe, R_EP3, 2);
+ if (tda_fail(ret))
+ goto fail;
regs[R_EB18] &= ~0x03; /* set agc1_gain to 6 dB */
- tda18271_write_regs(fe, R_EB18, 1);
+ ret = tda18271_write_regs(fe, R_EB18, 1);
+ if (tda_fail(ret))
+ goto fail;
regs[R_EB21] &= ~0x03; /* set agc2_gain to -15 dB */
@@ -500,9 +525,9 @@
regs[R_EB23] |= 0x04; /* forcelp_fc2_en = 1 */
regs[R_EB23] |= 0x02; /* lp_fc[2] = 1 */
- tda18271_write_regs(fe, R_EB21, 3);
-
- return 0;
+ ret = tda18271_write_regs(fe, R_EB21, 3);
+fail:
+ return ret;
}
static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
@@ -521,7 +546,7 @@
i = tda18271_lookup_rf_band(fe, &freq, NULL);
- if (i < 0)
+ if (tda_fail(i))
return i;
rf_default[RF1] = 1000 * map[i].rf1_def;
@@ -535,6 +560,8 @@
/* 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] = regs[R_EB14];
@@ -575,22 +602,29 @@
{
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);
- tda18271_powerscan_init(fe);
+ 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++)
+ 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);
-
- return 0;
+fail:
+ return ret;
}
/* ------------------------------------------------------------------ */
@@ -599,6 +633,7 @@
{
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)
@@ -607,15 +642,22 @@
if (priv->cal_initialized)
return 0;
- tda18271_calc_rf_filter_curve(fe);
+ ret = tda18271_calc_rf_filter_curve(fe);
+ if (tda_fail(ret))
+ goto fail;
- tda18271_por(fe);
+ ret = tda18271_por(fe);
+ if (tda_fail(ret))
+ goto fail;
tda_info("tda18271: RF tracking filter calibration complete\n");
priv->cal_initialized = true;
-
- return 0;
+ goto end;
+fail:
+ tda_info("tda18271: RF tracking filter calibration failed!\n");
+end:
+ return ret;
}
static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe,
@@ -623,6 +665,7 @@
{
struct tda18271_priv *priv = fe->tuner_priv;
unsigned char *regs = priv->tda18271_regs;
+ int ret;
u32 N = 0;
/* calculate bp filter */
@@ -671,7 +714,10 @@
tda18271_calc_main_pll(fe, N);
- tda18271_write_regs(fe, R_EP3, 11);
+ ret = tda18271_write_regs(fe, R_EP3, 11);
+ if (tda_fail(ret))
+ return ret;
+
msleep(5); /* RF tracking filter calibration initialization */
/* search for K,M,CO for RF calibration */
@@ -719,45 +765,56 @@
{
struct tda18271_priv *priv = fe->tuner_priv;
unsigned char *regs = priv->tda18271_regs;
+ int ret;
- tda18271_read_regs(fe);
+ ret = tda18271_read_regs(fe);
+ if (tda_fail(ret))
+ goto fail;
/* test IR_CAL_OK to see if we need init */
if ((regs[R_EP1] & 0x08) == 0)
- tda18271_init_regs(fe);
-
- return 0;
+ ret = tda18271_init_regs(fe);
+fail:
+ return ret;
}
static int tda18271_init(struct dvb_frontend *fe)
{
struct tda18271_priv *priv = fe->tuner_priv;
+ int ret;
mutex_lock(&priv->lock);
/* power up */
- tda18271_set_standby_mode(fe, 0, 0, 0);
+ ret = tda18271_set_standby_mode(fe, 0, 0, 0);
+ if (tda_fail(ret))
+ goto fail;
/* initialization */
- tda18271_ir_cal_init(fe);
+ 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 0;
+ 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);
- tda18271_init(fe);
+ ret = tda18271_init(fe);
+ if (tda_fail(ret))
+ goto fail;
mutex_lock(&priv->lock);
@@ -769,11 +826,11 @@
tda18271c2_rf_tracking_filters_correction(fe, freq);
break;
}
- tda18271_channel_configuration(fe, map, freq, bw);
+ ret = tda18271_channel_configuration(fe, map, freq, bw);
mutex_unlock(&priv->lock);
-
- return 0;
+fail:
+ return ret;
}
/* ------------------------------------------------------------------ */
@@ -837,7 +894,7 @@
ret = tda18271_tune(fe, map, freq, bw);
- if (ret < 0)
+ if (tda_fail(ret))
goto fail;
priv->frequency = freq;
@@ -893,7 +950,7 @@
ret = tda18271_tune(fe, map, freq, 0);
- if (ret < 0)
+ if (tda_fail(ret))
goto fail;
priv->frequency = freq;
@@ -905,16 +962,17 @@
static int tda18271_sleep(struct dvb_frontend *fe)
{
struct tda18271_priv *priv = fe->tuner_priv;
+ int ret;
mutex_lock(&priv->lock);
/* standby mode w/ slave tuner output
* & loop thru & xtal oscillator on */
- tda18271_set_standby_mode(fe, 1, 0, 0);
+ ret = tda18271_set_standby_mode(fe, 1, 0, 0);
mutex_unlock(&priv->lock);
- return 0;
+ return ret;
}
static int tda18271_release(struct dvb_frontend *fe)
@@ -1095,10 +1153,10 @@
if (cfg)
priv->small_i2c = cfg->small_i2c;
- if (tda18271_get_id(fe) < 0)
+ if (tda_fail(tda18271_get_id(fe)))
goto fail;
- if (tda18271_assign_map_layout(fe) < 0)
+ if (tda_fail(tda18271_assign_map_layout(fe)))
goto fail;
mutex_lock(&priv->lock);
diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h
index 2bc5eb3..81a7393 100644
--- a/drivers/media/common/tuners/tda18271-priv.h
+++ b/drivers/media/common/tuners/tda18271-priv.h
@@ -153,6 +153,15 @@
#define tda_reg(fmt, arg...) dprintk(KERN_DEBUG, DBG_REG, fmt, ##arg)
#define tda_cal(fmt, arg...) dprintk(KERN_DEBUG, DBG_CAL, fmt, ##arg)
+#define tda_fail(ret) \
+({ \
+ int __ret; \
+ __ret = (ret < 0); \
+ if (__ret) \
+ tda_printk(KERN_ERR, "error %d on line %d\n", ret, __LINE__);\
+ __ret; \
+})
+
/*---------------------------------------------------------------------*/
enum tda18271_map_type {
diff --git a/drivers/media/common/tuners/tea5767.c b/drivers/media/common/tuners/tea5767.c
index f6e7d7a..1f56463 100644
--- a/drivers/media/common/tuners/tea5767.c
+++ b/drivers/media/common/tuners/tea5767.c
@@ -373,14 +373,14 @@
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;
+ 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;
+ return -EINVAL;
}
/* Status bytes:
@@ -390,7 +390,7 @@
*/
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 -EINVAL;
}
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index 43d35bd..ceae6db 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -212,7 +212,7 @@
dprintk(1, "%s()\n", __func__);
if (priv->cfg->tuner_callback) {
- ret = priv->cfg->tuner_callback(priv->cfg->priv,
+ ret = priv->cfg->tuner_callback(priv->devptr,
XC5000_TUNER_RESET, 0);
if (ret)
printk(KERN_ERR "xc5000: reset failed\n");
@@ -900,9 +900,9 @@
.get_status = xc5000_get_status
};
-struct dvb_frontend * xc5000_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c,
- struct xc5000_config *cfg)
+struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c,
+ struct xc5000_config *cfg, void *devptr)
{
struct xc5000_priv *priv = NULL;
u16 id = 0;
@@ -916,6 +916,7 @@
priv->cfg = cfg;
priv->bandwidth = BANDWIDTH_6_MHZ;
priv->i2c = i2c;
+ priv->devptr = devptr;
/* Check if firmware has been loaded. It is possible that another
instance of the driver has loaded the firmware.
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h
index 0ee80f9..c910715 100644
--- a/drivers/media/common/tuners/xc5000.h
+++ b/drivers/media/common/tuners/xc5000.h
@@ -31,29 +31,31 @@
u8 i2c_address;
u32 if_khz;
- /* For each bridge framework, when it attaches either analog or digital,
- * it has to store a reference back to its _core equivalent structure,
- * so that it can service the hardware by steering gpio's etc.
- * Each bridge implementation is different so cast priv accordingly.
- * The xc5000 driver cares not for this value, other than ensuring
- * it's passed back to a bridge during tuner_callback().
- */
- void *priv;
int (*tuner_callback) (void *priv, int command, int arg);
};
/* xc5000 callback command */
#define XC5000_TUNER_RESET 0
+/* For each bridge framework, when it attaches either analog or digital,
+ * it has to store a reference back to its _core equivalent structure,
+ * so that it can service the hardware by steering gpio's etc.
+ * Each bridge implementation is different so cast devptr accordingly.
+ * The xc5000 driver cares not for this value, other than ensuring
+ * it's passed back to a bridge during tuner_callback().
+ */
+
#if defined(CONFIG_MEDIA_TUNER_XC5000) || \
(defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE))
extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c,
- struct xc5000_config *cfg);
+ struct xc5000_config *cfg,
+ void *devptr);
#else
static inline struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c,
- struct xc5000_config *cfg)
+ struct xc5000_config *cfg,
+ void *devptr)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
diff --git a/drivers/media/common/tuners/xc5000_priv.h b/drivers/media/common/tuners/xc5000_priv.h
index 13b2d19..ecebfe4 100644
--- a/drivers/media/common/tuners/xc5000_priv.h
+++ b/drivers/media/common/tuners/xc5000_priv.h
@@ -31,6 +31,8 @@
u8 video_standard;
u8 rf_mode;
u8 fwloaded;
+
+ void *devptr;
};
#endif
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 7b0ea3b..f9d0876 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -634,7 +634,7 @@
}
/* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
- fc->fe = dvb_attach(vp310_mt312_attach,
+ fc->fe = dvb_attach(mt312_attach,
&skystar23_samsung_tbdu18132_config, i2c);
if (fc->fe != NULL) {
ops = &fc->fe->ops;
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index d1239b8..7588db1 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -1,6 +1,7 @@
config DVB_BT8XX
tristate "BT8xx based PCI cards"
depends on DVB_CORE && PCI && I2C && VIDEO_BT848
+ depends on HOTPLUG # due to FW_LOADER
select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_SP887X if !DVB_FE_CUSTOMISE
select DVB_NXT6000 if !DVB_FE_CUSTOMISE
diff --git a/drivers/media/dvb/cinergyT2/Kconfig b/drivers/media/dvb/cinergyT2/Kconfig
index 3d778c5..c03513b 100644
--- a/drivers/media/dvb/cinergyT2/Kconfig
+++ b/drivers/media/dvb/cinergyT2/Kconfig
@@ -1,6 +1,6 @@
config DVB_CINERGYT2
tristate "Terratec CinergyT2/qanu USB2 DVB-T receiver"
- depends on DVB_CORE && USB
+ depends on DVB_CORE && USB && INPUT
help
Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 8cbdb0e..588fbe1 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -910,15 +910,21 @@
int curdelay = 100000000;
int slot;
+ /* Beware of too high polling frequency, because one polling
+ * call might take several hundred milliseconds until timeout!
+ */
for (slot = 0; slot < ca->slot_count; slot++) {
switch (ca->slot_info[slot].slot_state) {
default:
case DVB_CA_SLOTSTATE_NONE:
+ delay = HZ * 60; /* 60s */
+ if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
+ delay = HZ * 5; /* 5s */
+ break;
case DVB_CA_SLOTSTATE_INVALID:
- delay = HZ * 60;
- if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) {
- delay = HZ / 10;
- }
+ delay = HZ * 60; /* 60s */
+ if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
+ delay = HZ / 10; /* 100ms */
break;
case DVB_CA_SLOTSTATE_UNINITIALISED:
@@ -926,19 +932,17 @@
case DVB_CA_SLOTSTATE_VALIDATE:
case DVB_CA_SLOTSTATE_WAITFR:
case DVB_CA_SLOTSTATE_LINKINIT:
- delay = HZ / 10;
+ delay = HZ / 10; /* 100ms */
break;
case DVB_CA_SLOTSTATE_RUNNING:
- delay = HZ * 60;
- if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) {
- delay = HZ / 10;
- }
+ delay = HZ * 60; /* 60s */
+ if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE))
+ delay = HZ / 10; /* 100ms */
if (ca->open) {
if ((!ca->slot_info[slot].da_irq_supported) ||
- (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_DA))) {
- delay = HZ / 10;
- }
+ (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_DA)))
+ delay = HZ / 10; /* 100ms */
}
break;
}
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 4c1cff9..cf4584e 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -1,6 +1,7 @@
config DVB_USB
tristate "Support for various USB DVB devices"
depends on DVB_CORE && USB && I2C
+ depends on HOTPLUG # due to FW_LOADER
select FW_LOADER
help
By enabling this you will be able to choose the various supported
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 6d23846..c20553c 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -30,7 +30,7 @@
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_MT312
- tristate "Zarlink VP310/MT312 based"
+ tristate "Zarlink VP310/MT312/ZL10313 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
@@ -97,7 +97,7 @@
config DVB_SP8870
tristate "Spase sp8870 based"
- depends on DVB_CORE && I2C
+ depends on DVB_CORE && I2C && HOTPLUG
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
@@ -110,7 +110,7 @@
config DVB_SP887X
tristate "Spase sp887x based"
- depends on DVB_CORE && I2C
+ depends on DVB_CORE && I2C && HOTPLUG
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
@@ -144,7 +144,7 @@
config DVB_TDA1004X
tristate "Philips TDA10045H/TDA10046H based"
- depends on DVB_CORE && I2C
+ depends on DVB_CORE && I2C && HOTPLUG
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
@@ -211,7 +211,7 @@
config DVB_TDA10048
tristate "Philips TDA10048HN based"
- depends on DVB_CORE && I2C
+ depends on DVB_CORE && I2C && HOTPLUG
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
@@ -253,7 +253,7 @@
config DVB_NXT200X
tristate "NxtWave Communications NXT2002/NXT2004 based"
- depends on DVB_CORE && I2C
+ depends on DVB_CORE && I2C && HOTPLUG
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
@@ -268,7 +268,7 @@
config DVB_OR51211
tristate "Oren OR51211 based"
- depends on DVB_CORE && I2C
+ depends on DVB_CORE && I2C && HOTPLUG
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
@@ -281,7 +281,7 @@
config DVB_OR51132
tristate "Oren OR51132 based"
- depends on DVB_CORE && I2C
+ depends on DVB_CORE && I2C && HOTPLUG
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
@@ -297,7 +297,7 @@
config DVB_BCM3510
tristate "Broadcom BCM3510"
- depends on DVB_CORE && I2C
+ depends on DVB_CORE && I2C && HOTPLUG
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
diff --git a/drivers/media/dvb/frontends/itd1000.c b/drivers/media/dvb/frontends/itd1000.c
index 04c562c..600dad6 100644
--- a/drivers/media/dvb/frontends/itd1000.c
+++ b/drivers/media/dvb/frontends/itd1000.c
@@ -195,7 +195,7 @@
}
}
-struct {
+static const struct {
u32 freq;
u8 values[10]; /* RFTR, RFST1 - RFST9 */
} itd1000_fre_values[] = {
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
index 081ca33..5ac9b15 100644
--- a/drivers/media/dvb/frontends/mt312.c
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -737,7 +737,7 @@
}
#define MT312_SYS_CLK 90000000UL /* 90 MHz */
-static struct dvb_frontend_ops vp310_mt312_ops = {
+static struct dvb_frontend_ops mt312_ops = {
.info = {
.name = "Zarlink ???? DVB-S",
@@ -776,7 +776,7 @@
.set_voltage = mt312_set_voltage,
};
-struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config,
+struct dvb_frontend *mt312_attach(const struct mt312_config *config,
struct i2c_adapter *i2c)
{
struct mt312_state *state = NULL;
@@ -795,7 +795,7 @@
goto error;
/* create dvb_frontend */
- memcpy(&state->frontend.ops, &vp310_mt312_ops,
+ memcpy(&state->frontend.ops, &mt312_ops,
sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
@@ -827,12 +827,13 @@
kfree(state);
return NULL;
}
-EXPORT_SYMBOL(vp310_mt312_attach);
+EXPORT_SYMBOL(mt312_attach);
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
MODULE_DESCRIPTION("Zarlink VP310/MT312/ZL10313 DVB-S Demodulator driver");
MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
+MODULE_AUTHOR("Matthias Schwarzott <zzam@gentoo.org>");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h
index de796ea..29e3bb5 100644
--- a/drivers/media/dvb/frontends/mt312.h
+++ b/drivers/media/dvb/frontends/mt312.h
@@ -37,10 +37,10 @@
};
#if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE))
-struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config,
+struct dvb_frontend *mt312_attach(const struct mt312_config *config,
struct i2c_adapter *i2c);
#else
-static inline struct dvb_frontend *vp310_mt312_attach(
+static inline struct dvb_frontend *mt312_attach(
const struct mt312_config *config, struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index ae882432..d4339b1 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -5,6 +5,7 @@
config DVB_AV7110
tristate "AV7110 cards"
depends on DVB_CORE && PCI && I2C
+ depends on HOTPLUG
select FW_LOADER if !DVB_AV7110_FIRMWARE
select TTPCI_EEPROM
select VIDEO_SAA7146_VV
@@ -123,6 +124,7 @@
depends on DVB_BUDGET_CORE && I2C
select VIDEO_SAA7146_VV
depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV
+ depends on HOTPLUG # dependency of FW_LOADER
select DVB_PLL if !DVB_FE_CUSTOMISE
select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_TDA1004X if !DVB_FE_CUSTOMISE
diff --git a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/dvb/ttusb-dec/Kconfig
index 8361101..0712899 100644
--- a/drivers/media/dvb/ttusb-dec/Kconfig
+++ b/drivers/media/dvb/ttusb-dec/Kconfig
@@ -1,6 +1,7 @@
config DVB_TTUSB_DEC
tristate "Technotrend/Hauppauge USB DEC devices"
depends on DVB_CORE && USB
+ depends on HOTPLUG # due to FW_LOADER
select FW_LOADER
select CRC32
help
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index fe743aa..89d8d37 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -44,6 +44,10 @@
tristate
depends on I2C
+config VIDEO_TUNER
+ tristate
+ depends on MEDIA_TUNER
+
#
# Multimedia Video device configuration
#
@@ -690,7 +694,7 @@
tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
depends on PCI && VIDEO_V4L1 && I2C
select VIDEO_SAA7146_VV
- select MEDIA_TUNER
+ select VIDEO_TUNER
select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO
@@ -906,7 +910,7 @@
config SOC_CAMERA_MT9M001
tristate "mt9m001 support"
- depends on SOC_CAMERA
+ depends on SOC_CAMERA && I2C
select GPIO_PCA953X if MT9M001_PCA9536_SWITCH
help
This driver supports MT9M001 cameras from Micron, monochrome
@@ -921,7 +925,7 @@
config SOC_CAMERA_MT9V022
tristate "mt9v022 support"
- depends on SOC_CAMERA
+ depends on SOC_CAMERA && I2C
select GPIO_PCA953X if MT9V022_PCA9536_SWITCH
help
This driver supports MT9V022 cameras from Micron
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index a352c6e..dff0d6a 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -84,7 +84,7 @@
obj-$(CONFIG_VIDEO_DPC) += dpc7146.o
obj-$(CONFIG_TUNER_3036) += tuner-3036.o
-obj-$(CONFIG_MEDIA_TUNER) += tuner.o
+obj-$(CONFIG_VIDEO_TUNER) += tuner.o
obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig
index cab277f..def10d0 100644
--- a/drivers/media/video/au0828/Kconfig
+++ b/drivers/media/video/au0828/Kconfig
@@ -1,8 +1,9 @@
config VIDEO_AU0828
tristate "Auvitek AU0828 support"
- depends on VIDEO_DEV && I2C && INPUT && DVB_CORE
+ depends on VIDEO_DEV && I2C && INPUT && DVB_CORE && USB
select I2C_ALGOBIT
+ select VIDEO_TVEEPROM
select DVB_AU8522 if !DVB_FE_CUSTOMIZE
select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
---help---
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c
index 1371b4e..c86a5f17 100644
--- a/drivers/media/video/au0828/au0828-dvb.c
+++ b/drivers/media/video/au0828/au0828-dvb.c
@@ -337,12 +337,10 @@
dvb->frontend = dvb_attach(au8522_attach,
&hauppauge_hvr950q_config,
&dev->i2c_adap);
- if (dvb->frontend != NULL) {
- hauppauge_hvr950q_tunerconfig.priv = dev;
+ if (dvb->frontend != NULL)
dvb_attach(xc5000_attach, dvb->frontend,
&dev->i2c_adap,
- &hauppauge_hvr950q_tunerconfig);
- }
+ &hauppauge_hvr950q_tunerconfig, dev);
break;
default:
printk(KERN_WARNING "The frontend of your DVB/ATSC card "
diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig
index 7431ef6..24a34fc 100644
--- a/drivers/media/video/bt8xx/Kconfig
+++ b/drivers/media/video/bt8xx/Kconfig
@@ -1,12 +1,13 @@
config VIDEO_BT848
tristate "BT848 Video For Linux"
depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 && INPUT
+ depends on HOTPLUG # due to FW_LOADER
select I2C_ALGOBIT
select FW_LOADER
select VIDEO_BTCX
select VIDEOBUF_DMA_SG
select VIDEO_IR
- select MEDIA_TUNER
+ select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
index acc4b47..5f94269 100644
--- a/drivers/media/video/cx18/Kconfig
+++ b/drivers/media/video/cx18/Kconfig
@@ -1,14 +1,17 @@
config VIDEO_CX18
tristate "Conexant cx23418 MPEG encoder support"
depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
+ depends on INPUT # due to VIDEO_IR
+ depends on HOTPLUG # due to FW_LOADER
select I2C_ALGOBIT
select FW_LOADER
select VIDEO_IR
- select MEDIA_TUNER
+ select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEO_CX2341X
select VIDEO_CS5345
select DVB_S5H1409
+ select MEDIA_TUNER_MXL5005S
---help---
This is a video4linux driver for Conexant cx23418 based
PCI combo video recorder devices.
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index f5e3ba1..553adbf 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -47,11 +47,12 @@
static const struct cx18_card cx18_card_hvr1600_esmt = {
.type = CX18_CARD_HVR_1600_ESMT,
.name = "Hauppauge HVR-1600",
- .comment = "DVB & VBI are not yet supported\n",
+ .comment = "VBI is not yet supported\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_CX23418,
.hw_muxer = CX18_HW_CS5345,
- .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345,
+ .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
+ CX18_HW_CS5345 | CX18_HW_DVB,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 },
{ CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 },
@@ -86,11 +87,12 @@
static const struct cx18_card cx18_card_hvr1600_samsung = {
.type = CX18_CARD_HVR_1600_SAMSUNG,
.name = "Hauppauge HVR-1600 (Preproduction)",
- .comment = "DVB & VBI are not yet supported\n",
+ .comment = "VBI is not yet supported\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_CX23418,
.hw_muxer = CX18_HW_CS5345,
- .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345,
+ .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
+ CX18_HW_CS5345 | CX18_HW_DVB,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 },
{ CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 },
@@ -134,14 +136,15 @@
static const struct cx18_card cx18_card_h900 = {
.type = CX18_CARD_COMPRO_H900,
.name = "Compro VideoMate H900",
- .comment = "Not yet supported!\n",
- .v4l2_capabilities = 0,
+ .comment = "DVB & VBI are not yet supported\n",
+ .v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_CX23418,
.hw_all = CX18_HW_TUNER,
.video_inputs = {
- { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE7 },
- { CX18_CARD_INPUT_SVIDEO1, 1, CX23418_SVIDEO1 },
- { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
+ { CX18_CARD_INPUT_VID_TUNER, 0, CX23418_COMPOSITE2 },
+ { CX18_CARD_INPUT_SVIDEO1, 1,
+ CX23418_SVIDEO_LUMA3 | CX23418_SVIDEO_CHROMA4 },
+ { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE1 },
},
.audio_inputs = {
{ CX18_CARD_INPUT_AUD_TUNER,
@@ -163,6 +166,7 @@
.tune_lane = 0,
.initial_emrs = 0,
},
+ .xceive_pin = 15,
.pci_list = cx18_pci_h900,
.i2c = &cx18_i2c_std,
};
@@ -200,8 +204,6 @@
/* XC3028 tuner */
{ .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
},
- /* tuner reset */
- .gpio_init = { .direction = 0x1000, .initial_value = 0x1000 },
.ddr = {
/* Probably Samsung K4D263238G-VC33 memory */
.chip_config = 0x003,
@@ -211,6 +213,7 @@
.tune_lane = 0,
.initial_emrs = 2,
},
+ .xceive_pin = 15,
.pci_list = cx18_pci_mpc718,
.i2c = &cx18_i2c_std,
};
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index bca249b..bccb67f 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -114,8 +114,8 @@
/* The mask is the set of bits used by the operation */
struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */
- u16 direction; /* DIR setting. Leave to 0 if no init is needed */
- u16 initial_value;
+ u32 direction; /* DIR setting. Leave to 0 if no init is needed */
+ u32 initial_value;
};
struct cx18_card_tuner {
@@ -153,6 +153,7 @@
struct cx18_card_audio_input radio_input;
/* GPIO card-specific settings */
+ u8 xceive_pin; /* XCeive tuner GPIO reset pin */
struct cx18_gpio_init gpio_init;
struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS];
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 3f55d47..0dd4e05 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -164,16 +164,6 @@
MODULE_VERSION(CX18_VERSION);
-int cx18_waitq(wait_queue_head_t *waitq)
-{
- DEFINE_WAIT(wait);
-
- prepare_to_wait(waitq, &wait, TASK_INTERRUPTIBLE);
- schedule();
- finish_wait(waitq, &wait);
- return signal_pending(current) ? -EINTR : 0;
-}
-
/* Generic utility functions */
int cx18_msleep_timeout(unsigned int msecs, int intr)
{
@@ -220,13 +210,13 @@
/* Many thanks to Steven Toth from Hauppauge for providing the
model numbers */
+ /* Note: the Samsung memory models cannot be reliably determined
+ from the model number. Use the cardtype module option if you
+ have one of these preproduction models. */
switch (tv.model) {
- case 74000 ... 74099:
+ case 74000 ... 74999:
cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
break;
- case 74700 ... 74799:
- cx->card = cx18_get_card(CX18_CARD_HVR_1600_SAMSUNG);
- break;
case 0:
CX18_ERR("Invalid EEPROM\n");
return;
@@ -548,6 +538,7 @@
return 0;
}
+#ifdef MODULE
static u32 cx18_request_module(struct cx18 *cx, u32 hw,
const char *name, u32 id)
{
@@ -560,12 +551,14 @@
CX18_DEBUG_INFO("Loaded module %s\n", name);
return hw;
}
+#endif
static void cx18_load_and_init_modules(struct cx18 *cx)
{
u32 hw = cx->card->hw_all;
int i;
+#ifdef MODULE
/* load modules */
#ifndef CONFIG_MEDIA_TUNER
hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER);
@@ -573,6 +566,7 @@
#ifndef CONFIG_VIDEO_CS5345
hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345);
#endif
+#endif
/* check which i2c devices are actually found */
for (i = 0; i < 32; i++) {
@@ -801,7 +795,7 @@
return 0;
free_streams:
- cx18_streams_cleanup(cx);
+ cx18_streams_cleanup(cx, 1);
free_irq:
free_irq(cx->dev->irq, (void *)cx);
free_i2c:
@@ -904,14 +898,13 @@
cx18_halt_firmware(cx);
- cx18_streams_cleanup(cx);
+ cx18_streams_cleanup(cx, 1);
exit_cx18_i2c(cx);
free_irq(cx->dev->irq, (void *)cx);
- if (cx->dev)
- cx18_iounmap(cx);
+ cx18_iounmap(cx);
release_mem_region(cx->base_addr, CX18_MEM_SIZE);
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index 2ee9391..a2a6c58 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -444,9 +444,6 @@
/* Return non-zero if a signal is pending */
int cx18_msleep_timeout(unsigned int msecs, int intr);
-/* Wait on queue, returns -EINTR if interrupted */
-int cx18_waitq(wait_queue_head_t *waitq);
-
/* Read Hauppauge eeprom */
struct tveeprom; /* forward reference */
void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv);
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 65efe69..c974417 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -24,25 +24,27 @@
#include "cx18-streams.h"
#include "cx18-cards.h"
#include "s5h1409.h"
-
-/* Wait until the MXL500X driver is merged */
-#ifdef HAVE_MXL500X
-#include "mxl500x.h"
-#endif
+#include "mxl5005s.h"
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
#define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000
-#ifdef HAVE_MXL500X
-static struct mxl500x_config hauppauge_hvr1600_tuner = {
- .delsys = MXL500x_MODE_ATSC,
- .octf = MXL500x_OCTF_CH,
- .xtal_freq = 16000000,
- .iflo_freq = 5380000,
- .ref_freq = 322800000,
- .rssi_ena = MXL_RSSI_ENABLE,
- .addr = 0xC6 >> 1,
+static struct mxl5005s_config hauppauge_hvr1600_tuner = {
+ .i2c_address = 0xC6 >> 1,
+ .if_freq = IF_FREQ_5380000HZ,
+ .xtal_freq = CRYSTAL_FREQ_16000000HZ,
+ .agc_mode = MXL_SINGLE_AGC,
+ .tracking_filter = MXL_TF_C_H,
+ .rssi_enable = MXL_RSSI_ENABLE,
+ .cap_select = MXL_CAP_SEL_ENABLE,
+ .div_out = MXL_DIV_OUT_4,
+ .clock_out = MXL_CLOCK_OUT_DISABLE,
+ .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+ .top = MXL5005S_TOP_25P2,
+ .mod_mode = MXL_DIGITAL_MODE,
+ .if_mode = MXL_ZERO_IF,
+ .AgcMasterByte = 0x00,
};
static struct s5h1409_config hauppauge_hvr1600_config = {
@@ -55,7 +57,6 @@
.mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK
};
-#endif
static int dvb_register(struct cx18_stream *stream);
@@ -252,21 +253,18 @@
int ret = 0;
switch (cx->card->type) {
-/* Wait until the MXL500X driver is merged */
-#ifdef HAVE_MXL500X
case CX18_CARD_HVR_1600_ESMT:
case CX18_CARD_HVR_1600_SAMSUNG:
dvb->fe = dvb_attach(s5h1409_attach,
&hauppauge_hvr1600_config,
&cx->i2c_adap[0]);
if (dvb->fe != NULL) {
- dvb_attach(mxl500x_attach, dvb->fe,
- &hauppauge_hvr1600_tuner,
- &cx->i2c_adap[0]);
+ dvb_attach(mxl5005s_attach, dvb->fe,
+ &cx->i2c_adap[0],
+ &hauppauge_hvr1600_tuner);
ret = 0;
}
break;
-#endif
default:
/* No Digital Tv Support */
break;
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index 6930306..0b3141d 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -39,7 +39,7 @@
associated VBI streams are also automatically claimed.
Possible error returns: -EBUSY if someone else has claimed
the stream or 0 on success. */
-int cx18_claim_stream(struct cx18_open_id *id, int type)
+static int cx18_claim_stream(struct cx18_open_id *id, int type)
{
struct cx18 *cx = id->cx;
struct cx18_stream *s = &cx->streams[type];
@@ -87,7 +87,7 @@
/* This function releases a previously claimed stream. It will take into
account associated VBI streams. */
-void cx18_release_stream(struct cx18_stream *s)
+static void cx18_release_stream(struct cx18_stream *s)
{
struct cx18 *cx = s->cx;
struct cx18_stream *s_vbi;
@@ -662,6 +662,8 @@
for (x = 0; cx == NULL && x < cx18_cards_active; x++) {
/* find out which stream this open was on */
for (y = 0; y < CX18_MAX_STREAMS; y++) {
+ if (cx18_cards[x] == NULL)
+ continue;
s = &cx18_cards[x]->streams[y];
if (s->v4l2dev && s->v4l2dev->minor == minor) {
cx = cx18_cards[x];
diff --git a/drivers/media/video/cx18/cx18-fileops.h b/drivers/media/video/cx18/cx18-fileops.h
index 16cdafb..46da028 100644
--- a/drivers/media/video/cx18/cx18-fileops.h
+++ b/drivers/media/video/cx18/cx18-fileops.h
@@ -34,12 +34,3 @@
void cx18_mute(struct cx18 *cx);
void cx18_unmute(struct cx18 *cx);
-/* Utilities */
-
-/* Try to claim a stream for the filehandle. Return 0 on success,
- -EBUSY if stream already claimed. Once a stream is claimed, it
- remains claimed until the associated filehandle is closed. */
-int cx18_claim_stream(struct cx18_open_id *id, int type);
-
-/* Release a previously claimed stream. */
-void cx18_release_stream(struct cx18_stream *s);
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
index 19253e6..bb8bc86 100644
--- a/drivers/media/video/cx18/cx18-gpio.c
+++ b/drivers/media/video/cx18/cx18-gpio.c
@@ -35,6 +35,9 @@
#define CX18_REG_GPIO_OUT2 0xc78104
#define CX18_REG_GPIO_DIR2 0xc7810c
+static u32 gpio_dir;
+static u32 gpio_val;
+
/*
* HVR-1600 GPIO pins, courtesy of Hauppauge:
*
@@ -44,31 +47,53 @@
* gpio13: cs5345 reset pin
*/
+static void gpio_write(struct cx18 *cx)
+{
+ write_reg((gpio_dir & 0xffff) << 16, CX18_REG_GPIO_DIR1);
+ write_reg(((gpio_dir & 0xffff) << 16) | (gpio_val & 0xffff),
+ CX18_REG_GPIO_OUT1);
+ write_reg(gpio_dir & 0xffff0000, CX18_REG_GPIO_DIR2);
+ write_reg((gpio_dir & 0xffff0000) | ((gpio_val & 0xffff0000) >> 16),
+ CX18_REG_GPIO_OUT2);
+}
+
void cx18_gpio_init(struct cx18 *cx)
{
- if (cx->card->gpio_init.direction == 0)
+ gpio_dir = cx->card->gpio_init.direction;
+ gpio_val = cx->card->gpio_init.initial_value;
+
+ if (gpio_dir == 0)
return;
- CX18_DEBUG_INFO("GPIO initial dir: %08x out: %08x\n",
- read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_OUT1));
+ gpio_dir |= 1 << cx->card->xceive_pin;
+ gpio_val |= 1 << cx->card->xceive_pin;
- /* init output data then direction */
- write_reg(cx->card->gpio_init.direction << 16, CX18_REG_GPIO_DIR1);
- write_reg(0, CX18_REG_GPIO_DIR2);
- write_reg((cx->card->gpio_init.direction << 16) |
- cx->card->gpio_init.initial_value, CX18_REG_GPIO_OUT1);
- write_reg(0, CX18_REG_GPIO_OUT2);
+ CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n",
+ read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2),
+ read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2));
+
+ gpio_write(cx);
}
/* Xceive tuner reset function */
int cx18_reset_tuner_gpio(void *dev, int cmd, int value)
{
struct i2c_algo_bit_data *algo = dev;
- struct cx18 *cx = algo->data;
-/* int curdir, curout;*/
+ struct cx18_i2c_algo_callback_data *cb_data = algo->data;
+ struct cx18 *cx = cb_data->cx;
if (cmd != XC2028_TUNER_RESET)
return 0;
CX18_DEBUG_INFO("Resetting tuner\n");
+
+ gpio_dir |= 1 << cx->card->xceive_pin;
+ gpio_val &= ~(1 << cx->card->xceive_pin);
+
+ gpio_write(cx);
+ schedule_timeout_interruptible(msecs_to_jiffies(1));
+
+ gpio_val |= 1 << cx->card->xceive_pin;
+ gpio_write(cx);
+ schedule_timeout_interruptible(msecs_to_jiffies(1));
return 0;
}
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index 18c88d1..4f08a40 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -25,6 +25,7 @@
#include "cx18-cards.h"
#include "cx18-gpio.h"
#include "cx18-av-core.h"
+#include "cx18-i2c.h"
#include <media/ir-kbd-i2c.h>
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index 65af1bb..6990b77 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -26,17 +26,6 @@
#include "cx18-queue.h"
#include "cx18-scb.h"
-int cx18_buf_copy_from_user(struct cx18_stream *s, struct cx18_buffer *buf,
- const char __user *src, int copybytes)
-{
- if (s->buf_size - buf->bytesused < copybytes)
- copybytes = s->buf_size - buf->bytesused;
- if (copy_from_user(buf->buf + buf->bytesused, src, copybytes))
- return -EFAULT;
- buf->bytesused += copybytes;
- return copybytes;
-}
-
void cx18_buf_swap(struct cx18_buffer *buf)
{
int i;
@@ -159,8 +148,9 @@
-ENOMEM is returned if the buffers could not be obtained, 0 if all
buffers where obtained from the 'from' list and if non-zero then
the number of stolen buffers is returned. */
-int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
- struct cx18_queue *steal, struct cx18_queue *to, int needed_bytes)
+static int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
+ struct cx18_queue *steal, struct cx18_queue *to,
+ int needed_bytes)
{
unsigned long flags;
int rc = 0;
@@ -239,12 +229,12 @@
/* allocate stream buffers. Initially all buffers are in q_free. */
for (i = 0; i < s->buffers; i++) {
- struct cx18_buffer *buf =
- kzalloc(sizeof(struct cx18_buffer), GFP_KERNEL);
+ struct cx18_buffer *buf = kzalloc(sizeof(struct cx18_buffer),
+ GFP_KERNEL|__GFP_NOWARN);
if (buf == NULL)
break;
- buf->buf = kmalloc(s->buf_size, GFP_KERNEL);
+ buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN);
if (buf->buf == NULL) {
kfree(buf);
break;
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
index f86c8a6..91423b9 100644
--- a/drivers/media/video/cx18/cx18-queue.h
+++ b/drivers/media/video/cx18/cx18-queue.h
@@ -39,8 +39,6 @@
s->buf_size, s->dma);
}
-int cx18_buf_copy_from_user(struct cx18_stream *s, struct cx18_buffer *buf,
- const char __user *src, int copybytes);
void cx18_buf_swap(struct cx18_buffer *buf);
/* cx18_queue utility functions */
@@ -48,8 +46,6 @@
void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
struct cx18_queue *q);
struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
-int cx18_queue_move(struct cx18_stream *s, struct cx18_queue *from,
- struct cx18_queue *steal, struct cx18_queue *to, int needed_bytes);
struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id,
u32 bytesused);
void cx18_flush_queues(struct cx18_stream *s);
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index afb141b..4ca9d84 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -218,7 +218,7 @@
return 0;
/* One or more streams could not be initialized. Clean 'em all up. */
- cx18_streams_cleanup(cx);
+ cx18_streams_cleanup(cx, 0);
return -ENOMEM;
}
@@ -296,12 +296,12 @@
return 0;
/* One or more streams could not be initialized. Clean 'em all up. */
- cx18_streams_cleanup(cx);
+ cx18_streams_cleanup(cx, 1);
return -ENOMEM;
}
/* Unregister v4l2 devices */
-void cx18_streams_cleanup(struct cx18 *cx)
+void cx18_streams_cleanup(struct cx18 *cx, int unregister)
{
struct video_device *vdev;
int type;
@@ -319,8 +319,11 @@
cx18_stream_free(&cx->streams[type]);
- /* Unregister device */
- video_unregister_device(vdev);
+ /* Unregister or release device */
+ if (unregister)
+ video_unregister_device(vdev);
+ else
+ video_device_release(vdev);
}
}
diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h
index 8c7ba7d..f327e94 100644
--- a/drivers/media/video/cx18/cx18-streams.h
+++ b/drivers/media/video/cx18/cx18-streams.h
@@ -24,7 +24,7 @@
u32 cx18_find_handle(struct cx18 *cx);
int cx18_streams_setup(struct cx18 *cx);
int cx18_streams_register(struct cx18 *cx);
-void cx18_streams_cleanup(struct cx18 *cx);
+void cx18_streams_cleanup(struct cx18 *cx, int unregister);
/* Capture related */
int cx18_start_v4l2_encode_stream(struct cx18_stream *s);
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index cadf936..7bf14c9 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -1,18 +1,20 @@
config VIDEO_CX23885
tristate "Conexant cx23885 (2388x successor) support"
depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT
+ depends on HOTPLUG # due to FW_LOADER
select I2C_ALGOBIT
select FW_LOADER
select VIDEO_BTCX
- select MEDIA_TUNER
+ select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEO_IR
select VIDEOBUF_DVB
select VIDEO_CX25840
+ select VIDEO_CX2341X
+ select DVB_DIB7000P if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_MT2131 if !DVB_FE_CUSTOMISE
select DVB_S5H1409 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X if !DVB_FE_CUSTOMISE
- select DVB_PLL if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMIZE
select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE
select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 6ebf587..20e05f2 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -200,6 +200,10 @@
.card = CX23885_BOARD_HAUPPAUGE_HVR1200,
}, {
.subvendor = 0x0070,
+ .subdevice = 0x71d3,
+ .card = CX23885_BOARD_HAUPPAUGE_HVR1200,
+ }, {
+ .subvendor = 0x0070,
.subdevice = 0x8101,
.card = CX23885_BOARD_HAUPPAUGE_HVR1700,
}, {
@@ -245,6 +249,33 @@
/* Make sure we support the board model */
switch (tv.model)
{
+ case 71009:
+ /* WinTV-HVR1200 (PCIe, Retail, full height)
+ * DVB-T and basic analog */
+ case 71359:
+ /* WinTV-HVR1200 (PCIe, OEM, half height)
+ * DVB-T and basic analog */
+ case 71439:
+ /* WinTV-HVR1200 (PCIe, OEM, half height)
+ * DVB-T and basic analog */
+ case 71449:
+ /* WinTV-HVR1200 (PCIe, OEM, full height)
+ * DVB-T and basic analog */
+ case 71939:
+ /* WinTV-HVR1200 (PCIe, OEM, half height)
+ * DVB-T and basic analog */
+ case 71949:
+ /* WinTV-HVR1200 (PCIe, OEM, full height)
+ * DVB-T and basic analog */
+ case 71959:
+ /* WinTV-HVR1200 (PCIe, OEM, full height)
+ * DVB-T and basic analog */
+ case 71979:
+ /* WinTV-HVR1200 (PCIe, OEM, half height)
+ * DVB-T and basic analog */
+ case 71999:
+ /* WinTV-HVR1200 (PCIe, OEM, full height)
+ * DVB-T and basic analog */
case 76601: /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual channel ATSC and MPEG2 HW Encoder */
case 77001: /* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC and Basic analog */
case 77011: /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC and Basic analog */
@@ -263,8 +294,11 @@
case 80019:
/* WinTV-HVR1400 (Express Card, Retail, IR,
* DVB-T and Basic analog */
+ case 81509:
+ /* WinTV-HVR1700 (PCIe, OEM, No IR, half height)
+ * DVB-T and MPEG2 HW Encoder */
case 81519:
- /* WinTV-HVR1700 (PCIe, Retail, No IR, half height,
+ /* WinTV-HVR1700 (PCIe, OEM, No IR, full height)
* DVB-T and MPEG2 HW Encoder */
break;
default:
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index f056497..022aa39 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -37,7 +37,6 @@
#include "lgdt330x.h"
#include "xc5000.h"
#include "tda10048.h"
-#include "dvb-pll.h"
#include "tuner-xc2028.h"
#include "tuner-simple.h"
#include "dib7000p.h"
@@ -385,12 +384,10 @@
port->dvb.frontend = dvb_attach(s5h1409_attach,
&hauppauge_hvr1500q_config,
&dev->i2c_bus[0].i2c_adap);
- if (port->dvb.frontend != NULL) {
- hauppauge_hvr1500q_tunerconfig.priv = i2c_bus;
+ if (port->dvb.frontend != NULL)
dvb_attach(xc5000_attach, port->dvb.frontend,
&i2c_bus->i2c_adap,
- &hauppauge_hvr1500q_tunerconfig);
- }
+ &hauppauge_hvr1500q_tunerconfig, i2c_bus);
break;
case CX23885_BOARD_HAUPPAUGE_HVR1500:
i2c_bus = &dev->i2c_bus[1];
diff --git a/drivers/media/video/cx25840/Kconfig b/drivers/media/video/cx25840/Kconfig
index 7cf29a0..448f4cd 100644
--- a/drivers/media/video/cx25840/Kconfig
+++ b/drivers/media/video/cx25840/Kconfig
@@ -1,6 +1,7 @@
config VIDEO_CX25840
tristate "Conexant CX2584x audio/video decoders"
depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ depends on HOTPLUG # due to FW_LOADER
select FW_LOADER
---help---
Support for the Conexant CX2584x audio/video decoders.
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index b0d7d6a..10e20d8 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -2,10 +2,9 @@
tristate "Conexant 2388x (bt878 successor) support"
depends on VIDEO_DEV && PCI && I2C && INPUT
select I2C_ALGOBIT
- select FW_LOADER
select VIDEO_BTCX
select VIDEOBUF_DMA_SG
- select MEDIA_TUNER
+ select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEO_IR
select VIDEO_WM8775 if VIDEO_HELPER_CHIPS_AUTO
@@ -34,8 +33,9 @@
config VIDEO_CX88_BLACKBIRD
tristate "Blackbird MPEG encoder support (cx2388x + cx23416)"
- depends on VIDEO_CX88
+ depends on VIDEO_CX88 && HOTPLUG
select VIDEO_CX2341X
+ select FW_LOADER
---help---
This adds support for MPEG encoder cards based on the
Blackbird reference design, using the Conexant 2388x
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 1c7fe68..d96173f 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -509,9 +509,6 @@
if (!fe) {
printk(KERN_ERR "%s/2: xc3028 attach failed\n",
dev->core->name);
- dvb_frontend_detach(dev->dvb.frontend);
- dvb_unregister_frontend(dev->dvb.frontend);
- dev->dvb.frontend = NULL;
return -EINVAL;
}
@@ -523,20 +520,23 @@
static int dvb_register(struct cx8802_dev *dev)
{
+ struct cx88_core *core = dev->core;
+
/* init struct videobuf_dvb */
- dev->dvb.name = dev->core->name;
+ dev->dvb.name = core->name;
dev->ts_gen_cntrl = 0x0c;
/* init frontend */
- switch (dev->core->boardnr) {
+ switch (core->boardnr) {
case CX88_BOARD_HAUPPAUGE_DVB_T1:
dev->dvb.frontend = dvb_attach(cx22702_attach,
&connexant_refboard_config,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
- &dev->core->i2c_adap,
- DVB_PLL_THOMSON_DTT759X);
+ if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ 0x61, &core->i2c_adap,
+ DVB_PLL_THOMSON_DTT759X))
+ goto frontend_detach;
}
break;
case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
@@ -545,11 +545,12 @@
case CX88_BOARD_WINFAST_DTV1000:
dev->dvb.frontend = dvb_attach(cx22702_attach,
&connexant_refboard_config,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
- &dev->core->i2c_adap,
- DVB_PLL_THOMSON_DTT7579);
+ if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ 0x60, &core->i2c_adap,
+ DVB_PLL_THOMSON_DTT7579))
+ goto frontend_detach;
}
break;
case CX88_BOARD_WINFAST_DTV2000H:
@@ -559,29 +560,32 @@
case CX88_BOARD_HAUPPAUGE_HVR3000:
dev->dvb.frontend = dvb_attach(cx22702_attach,
&hauppauge_hvr_config,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_attach(simple_tuner_attach, dev->dvb.frontend,
- &dev->core->i2c_adap, 0x61,
- TUNER_PHILIPS_FMD1216ME_MK3);
+ if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ &core->i2c_adap, 0x61,
+ TUNER_PHILIPS_FMD1216ME_MK3))
+ goto frontend_detach;
}
break;
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
dev->dvb.frontend = dvb_attach(mt352_attach,
&dvico_fusionhdtv,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
- NULL, DVB_PLL_THOMSON_DTT7579);
+ if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
+ goto frontend_detach;
break;
}
/* ZL10353 replaces MT352 on later cards */
dev->dvb.frontend = dvb_attach(zl10353_attach,
&dvico_fusionhdtv_plus_v1_1,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
- NULL, DVB_PLL_THOMSON_DTT7579);
+ if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ 0x60, NULL, DVB_PLL_THOMSON_DTT7579))
+ goto frontend_detach;
}
break;
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
@@ -589,28 +593,31 @@
* compatible, with a slightly different MT352 AGC gain. */
dev->dvb.frontend = dvb_attach(mt352_attach,
&dvico_fusionhdtv_dual,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
- NULL, DVB_PLL_THOMSON_DTT7579);
+ if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
+ goto frontend_detach;
break;
}
/* ZL10353 replaces MT352 on later cards */
dev->dvb.frontend = dvb_attach(zl10353_attach,
&dvico_fusionhdtv_plus_v1_1,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
- NULL, DVB_PLL_THOMSON_DTT7579);
+ if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ 0x61, NULL, DVB_PLL_THOMSON_DTT7579))
+ goto frontend_detach;
}
break;
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
dev->dvb.frontend = dvb_attach(mt352_attach,
&dvico_fusionhdtv,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
- NULL, DVB_PLL_LG_Z201);
+ if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ 0x61, NULL, DVB_PLL_LG_Z201))
+ goto frontend_detach;
}
break;
case CX88_BOARD_KWORLD_DVB_T:
@@ -618,10 +625,11 @@
case CX88_BOARD_ADSTECH_DVB_T_PCI:
dev->dvb.frontend = dvb_attach(mt352_attach,
&dntv_live_dvbt_config,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
- NULL, DVB_PLL_UNKNOWN_1);
+ if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ 0x61, NULL, DVB_PLL_UNKNOWN_1))
+ goto frontend_detach;
}
break;
case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
@@ -630,32 +638,35 @@
dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
&dev->vp3054->adap);
if (dev->dvb.frontend != NULL) {
- dvb_attach(simple_tuner_attach, dev->dvb.frontend,
- &dev->core->i2c_adap, 0x61,
- TUNER_PHILIPS_FMD1216ME_MK3);
+ if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ &core->i2c_adap, 0x61,
+ TUNER_PHILIPS_FMD1216ME_MK3))
+ goto frontend_detach;
}
#else
- printk(KERN_ERR "%s/2: built without vp3054 support\n", dev->core->name);
+ printk(KERN_ERR "%s/2: built without vp3054 support\n",
+ core->name);
#endif
break;
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
dev->dvb.frontend = dvb_attach(zl10353_attach,
&dvico_fusionhdtv_hybrid,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_attach(simple_tuner_attach, dev->dvb.frontend,
- &dev->core->i2c_adap, 0x61,
- TUNER_THOMSON_FE6600);
+ if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ &core->i2c_adap, 0x61,
+ TUNER_THOMSON_FE6600))
+ goto frontend_detach;
}
break;
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
dev->dvb.frontend = dvb_attach(zl10353_attach,
&dvico_fusionhdtv_xc3028,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend == NULL)
dev->dvb.frontend = dvb_attach(mt352_attach,
&dvico_fusionhdtv_mt352_xc3028,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
/*
* On this board, the demod provides the I2C bus pullup.
* We must not permit gate_ctrl to be performed, or
@@ -668,19 +679,18 @@
break;
case CX88_BOARD_PCHDTV_HD3000:
dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_attach(simple_tuner_attach, dev->dvb.frontend,
- &dev->core->i2c_adap, 0x61,
- TUNER_THOMSON_DTT761X);
+ if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ &core->i2c_adap, 0x61,
+ TUNER_THOMSON_DTT761X))
+ goto frontend_detach;
}
break;
case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
dev->ts_gen_cntrl = 0x08;
- {
- /* Do a hardware reset of chip before using it. */
- struct cx88_core *core = dev->core;
+ /* Do a hardware reset of chip before using it. */
cx_clear(MO_GP0_IO, 1);
mdelay(100);
cx_set(MO_GP0_IO, 1);
@@ -690,139 +700,137 @@
fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
dev->dvb.frontend = dvb_attach(lgdt330x_attach,
&fusionhdtv_3_gold,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_attach(simple_tuner_attach, dev->dvb.frontend,
- &dev->core->i2c_adap, 0x61,
- TUNER_MICROTUNE_4042FI5);
- }
+ if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ &core->i2c_adap, 0x61,
+ TUNER_MICROTUNE_4042FI5))
+ goto frontend_detach;
}
break;
case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
dev->ts_gen_cntrl = 0x08;
- {
- /* Do a hardware reset of chip before using it. */
- struct cx88_core *core = dev->core;
+ /* Do a hardware reset of chip before using it. */
cx_clear(MO_GP0_IO, 1);
mdelay(100);
cx_set(MO_GP0_IO, 9);
mdelay(200);
dev->dvb.frontend = dvb_attach(lgdt330x_attach,
&fusionhdtv_3_gold,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_attach(simple_tuner_attach, dev->dvb.frontend,
- &dev->core->i2c_adap, 0x61,
- TUNER_THOMSON_DTT761X);
- }
+ if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ &core->i2c_adap, 0x61,
+ TUNER_THOMSON_DTT761X))
+ goto frontend_detach;
}
break;
case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
dev->ts_gen_cntrl = 0x08;
- {
- /* Do a hardware reset of chip before using it. */
- struct cx88_core *core = dev->core;
+ /* Do a hardware reset of chip before using it. */
cx_clear(MO_GP0_IO, 1);
mdelay(100);
cx_set(MO_GP0_IO, 1);
mdelay(200);
dev->dvb.frontend = dvb_attach(lgdt330x_attach,
&fusionhdtv_5_gold,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_attach(simple_tuner_attach, dev->dvb.frontend,
- &dev->core->i2c_adap, 0x61,
- TUNER_LG_TDVS_H06XF);
- dvb_attach(tda9887_attach, dev->dvb.frontend,
- &dev->core->i2c_adap, 0x43);
- }
+ if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ &core->i2c_adap, 0x61,
+ TUNER_LG_TDVS_H06XF))
+ goto frontend_detach;
+ if (!dvb_attach(tda9887_attach, dev->dvb.frontend,
+ &core->i2c_adap, 0x43))
+ goto frontend_detach;
}
break;
case CX88_BOARD_PCHDTV_HD5500:
dev->ts_gen_cntrl = 0x08;
- {
- /* Do a hardware reset of chip before using it. */
- struct cx88_core *core = dev->core;
+ /* Do a hardware reset of chip before using it. */
cx_clear(MO_GP0_IO, 1);
mdelay(100);
cx_set(MO_GP0_IO, 1);
mdelay(200);
dev->dvb.frontend = dvb_attach(lgdt330x_attach,
&pchdtv_hd5500,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_attach(simple_tuner_attach, dev->dvb.frontend,
- &dev->core->i2c_adap, 0x61,
- TUNER_LG_TDVS_H06XF);
- dvb_attach(tda9887_attach, dev->dvb.frontend,
- &dev->core->i2c_adap, 0x43);
- }
+ if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ &core->i2c_adap, 0x61,
+ TUNER_LG_TDVS_H06XF))
+ goto frontend_detach;
+ if (!dvb_attach(tda9887_attach, dev->dvb.frontend,
+ &core->i2c_adap, 0x43))
+ goto frontend_detach;
}
break;
case CX88_BOARD_ATI_HDTVWONDER:
dev->dvb.frontend = dvb_attach(nxt200x_attach,
&ati_hdtvwonder,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend != NULL) {
- dvb_attach(simple_tuner_attach, dev->dvb.frontend,
- &dev->core->i2c_adap, 0x61,
- TUNER_PHILIPS_TUV1236D);
+ if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ &core->i2c_adap, 0x61,
+ TUNER_PHILIPS_TUV1236D))
+ goto frontend_detach;
}
break;
case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
dev->dvb.frontend = dvb_attach(cx24123_attach,
&hauppauge_novas_config,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend) {
- dvb_attach(isl6421_attach, dev->dvb.frontend,
- &dev->core->i2c_adap, 0x08, 0x00, 0x00);
+ if (!dvb_attach(isl6421_attach, dev->dvb.frontend,
+ &core->i2c_adap, 0x08, 0x00, 0x00))
+ goto frontend_detach;
}
break;
case CX88_BOARD_KWORLD_DVBS_100:
dev->dvb.frontend = dvb_attach(cx24123_attach,
&kworld_dvbs_100_config,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend) {
- dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
+ core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
}
break;
case CX88_BOARD_GENIATECH_DVBS:
dev->dvb.frontend = dvb_attach(cx24123_attach,
&geniatech_dvbs_config,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend) {
- dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
+ core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
}
break;
case CX88_BOARD_PINNACLE_PCTV_HD_800i:
dev->dvb.frontend = dvb_attach(s5h1409_attach,
&pinnacle_pctv_hd_800i_config,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend != NULL) {
/* tuner_config.video_dev must point to
* i2c_adap.algo_data
*/
- pinnacle_pctv_hd_800i_tuner_config.priv =
- dev->core->i2c_adap.algo_data;
- dvb_attach(xc5000_attach, dev->dvb.frontend,
- &dev->core->i2c_adap,
- &pinnacle_pctv_hd_800i_tuner_config);
+ if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
+ &core->i2c_adap,
+ &pinnacle_pctv_hd_800i_tuner_config,
+ core->i2c_adap.algo_data))
+ goto frontend_detach;
}
break;
case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
dev->dvb.frontend = dvb_attach(s5h1409_attach,
&dvico_hdtv5_pci_nano_config,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend != NULL) {
struct dvb_frontend *fe;
struct xc2028_config cfg = {
- .i2c_adap = &dev->core->i2c_adap,
+ .i2c_adap = &core->i2c_adap,
.i2c_addr = 0x61,
.callback = cx88_pci_nano_callback,
};
@@ -841,50 +849,50 @@
case CX88_BOARD_PINNACLE_HYBRID_PCTV:
dev->dvb.frontend = dvb_attach(zl10353_attach,
&cx88_geniatech_x8000_mt,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (attach_xc3028(0x61, dev) < 0)
- return -EINVAL;
+ goto frontend_detach;
break;
case CX88_BOARD_GENIATECH_X8000_MT:
dev->ts_gen_cntrl = 0x00;
dev->dvb.frontend = dvb_attach(zl10353_attach,
&cx88_geniatech_x8000_mt,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (attach_xc3028(0x61, dev) < 0)
- return -EINVAL;
+ goto frontend_detach;
break;
case CX88_BOARD_KWORLD_ATSC_120:
dev->dvb.frontend = dvb_attach(s5h1409_attach,
&kworld_atsc_120_config,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (attach_xc3028(0x61, dev) < 0)
- return -EINVAL;
+ goto frontend_detach;
break;
case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
dev->dvb.frontend = dvb_attach(s5h1411_attach,
&dvico_fusionhdtv7_config,
- &dev->core->i2c_adap);
+ &core->i2c_adap);
if (dev->dvb.frontend != NULL) {
/* tuner_config.video_dev must point to
* i2c_adap.algo_data
*/
- dvico_fusionhdtv7_tuner_config.priv =
- dev->core->i2c_adap.algo_data;
- dvb_attach(xc5000_attach, dev->dvb.frontend,
- &dev->core->i2c_adap,
- &dvico_fusionhdtv7_tuner_config);
+ if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
+ &core->i2c_adap,
+ &dvico_fusionhdtv7_tuner_config,
+ core->i2c_adap.algo_data))
+ goto frontend_detach;
}
break;
default:
printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
- dev->core->name);
+ core->name);
break;
}
if (NULL == dev->dvb.frontend) {
printk(KERN_ERR
"%s/2: frontend initialization failed\n",
- dev->core->name);
+ core->name);
return -EINVAL;
}
@@ -892,11 +900,18 @@
dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
/* Put the analog decoder in standby to keep it quiet */
- cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
+ cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL);
/* register everything */
return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev,
&dev->pci->dev, adapter_nr);
+
+frontend_detach:
+ if (dev->dvb.frontend) {
+ dvb_frontend_detach(dev->dvb.frontend);
+ dev->dvb.frontend = NULL;
+ }
+ return -EINVAL;
}
/* ----------------------------------------------------------- */
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
index c7c2896..16a5af3 100644
--- a/drivers/media/video/em28xx/Kconfig
+++ b/drivers/media/video/em28xx/Kconfig
@@ -1,7 +1,7 @@
config VIDEO_EM28XX
tristate "Empia EM28xx USB video capture support"
depends on VIDEO_DEV && I2C && INPUT
- select MEDIA_TUNER
+ select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEO_IR
select VIDEOBUF_VMALLOC
@@ -35,7 +35,6 @@
select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
select VIDEOBUF_DVB
- select FW_LOADER
---help---
This adds support for DVB cards based on the
Empiatech em28xx chips.
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 50ccf37..3e4f3c7 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -420,7 +420,13 @@
.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
{ USB_DEVICE(0x2040, 0x6502),
.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
- { USB_DEVICE(0x2040, 0x6513),
+ { USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */
+ .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+ { USB_DEVICE(0x2040, 0x6517), /* HP HVR-950 */
+ .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+ { USB_DEVICE(0x2040, 0x651b), /* RP HVR-950 */
+ .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
+ { USB_DEVICE(0x2040, 0x651f), /* HCW HVR-850 */
.driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
{ USB_DEVICE(0x0ccd, 0x0042),
.driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS },
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index 7df81575..8cf4983 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -251,7 +251,6 @@
printk(KERN_ERR "%s/2: xc3028 attach failed\n",
dev->name);
dvb_frontend_detach(dev->dvb->frontend);
- dvb_unregister_frontend(dev->dvb->frontend);
dev->dvb->frontend = NULL;
return -EINVAL;
}
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig
index eec115b..5d7ee8f 100644
--- a/drivers/media/video/ivtv/Kconfig
+++ b/drivers/media/video/ivtv/Kconfig
@@ -1,10 +1,12 @@
config VIDEO_IVTV
tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support"
depends on VIDEO_V4L1 && VIDEO_V4L2 && PCI && I2C && EXPERIMENTAL
+ depends on INPUT # due to VIDEO_IR
+ depends on HOTPLUG # due to FW_LOADER
select I2C_ALGOBIT
select FW_LOADER
select VIDEO_IR
- select MEDIA_TUNER
+ select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEO_CX2341X
select VIDEO_CX25840
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
index 8c02fa6..c7e449f 100644
--- a/drivers/media/video/ivtv/ivtv-controls.c
+++ b/drivers/media/video/ivtv/ivtv-controls.c
@@ -181,12 +181,12 @@
return 0;
}
/* Need sliced data for mpeg insertion */
- if (get_service_set(itv->vbi.sliced_in) == 0) {
+ if (ivtv_get_service_set(itv->vbi.sliced_in) == 0) {
if (itv->is_60hz)
itv->vbi.sliced_in->service_set = V4L2_SLICED_CAPTION_525;
else
itv->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625;
- expand_service_set(itv->vbi.sliced_in, itv->is_50hz);
+ ivtv_expand_service_set(itv->vbi.sliced_in, itv->is_50hz);
}
return 0;
}
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index ed020f7..797e636 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -853,6 +853,7 @@
return 0;
}
+#ifdef MODULE
static u32 ivtv_request_module(struct ivtv *itv, u32 hw,
const char *name, u32 id)
{
@@ -865,12 +866,14 @@
IVTV_DEBUG_INFO("Loaded module %s\n", name);
return hw;
}
+#endif
static void ivtv_load_and_init_modules(struct ivtv *itv)
{
u32 hw = itv->card->hw_all;
unsigned i;
+#ifdef MODULE
/* load modules */
#ifndef CONFIG_MEDIA_TUNER
hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER);
@@ -911,6 +914,7 @@
#ifndef CONFIG_VIDEO_M52790
hw = ivtv_request_module(itv, hw, "m52790", IVTV_HW_M52790);
#endif
+#endif
/* check which i2c devices are actually found */
for (i = 0; i < 32; i++) {
@@ -1228,7 +1232,7 @@
return 0;
free_streams:
- ivtv_streams_cleanup(itv);
+ ivtv_streams_cleanup(itv, 1);
free_irq:
free_irq(itv->dev->irq, (void *)itv);
free_i2c:
@@ -1373,7 +1377,7 @@
flush_workqueue(itv->irq_work_queues);
destroy_workqueue(itv->irq_work_queues);
- ivtv_streams_cleanup(itv);
+ ivtv_streams_cleanup(itv, 1);
ivtv_udma_free(itv);
exit_ivtv_i2c(itv);
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index 2b74b0a..f2fa434 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -987,6 +987,8 @@
/* Find which card this open was on */
spin_lock(&ivtv_cards_lock);
for (x = 0; itv == NULL && x < ivtv_cards_active; x++) {
+ if (ivtv_cards[x] == NULL)
+ continue;
/* find out which stream this open was on */
for (y = 0; y < IVTV_MAX_STREAMS; y++) {
s = &ivtv_cards[x]->streams[y];
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index d508b5d..26cc0f6 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -38,7 +38,7 @@
#include <linux/dvb/audio.h>
#include <linux/i2c-id.h>
-u16 service2vbi(int type)
+u16 ivtv_service2vbi(int type)
{
switch (type) {
case V4L2_SLICED_TELETEXT_B:
@@ -88,7 +88,7 @@
return 0;
}
-void expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
+void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
{
u16 set = fmt->service_set;
int f, l;
@@ -115,7 +115,7 @@
return set != 0;
}
-u16 get_service_set(struct v4l2_sliced_vbi_format *fmt)
+u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt)
{
int f, l;
u16 set = 0;
@@ -466,7 +466,7 @@
vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
}
- vbifmt->service_set = get_service_set(vbifmt);
+ vbifmt->service_set = ivtv_get_service_set(vbifmt);
break;
}
@@ -481,12 +481,12 @@
if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
V4L2_SLICED_VBI_525;
- expand_service_set(vbifmt, itv->is_50hz);
+ ivtv_expand_service_set(vbifmt, itv->is_50hz);
break;
}
itv->video_dec_func(itv, VIDIOC_G_FMT, fmt);
- vbifmt->service_set = get_service_set(vbifmt);
+ vbifmt->service_set = ivtv_get_service_set(vbifmt);
break;
}
case V4L2_BUF_TYPE_VBI_OUTPUT:
@@ -640,9 +640,9 @@
memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
if (vbifmt->service_set)
- expand_service_set(vbifmt, itv->is_50hz);
+ ivtv_expand_service_set(vbifmt, itv->is_50hz);
set = check_service_set(vbifmt, itv->is_50hz);
- vbifmt->service_set = get_service_set(vbifmt);
+ vbifmt->service_set = ivtv_get_service_set(vbifmt);
if (!set_fmt)
return 0;
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.h b/drivers/media/video/ivtv/ivtv-ioctl.h
index a03351b..4e67f0e 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.h
+++ b/drivers/media/video/ivtv/ivtv-ioctl.h
@@ -21,9 +21,9 @@
#ifndef IVTV_IOCTL_H
#define IVTV_IOCTL_H
-u16 service2vbi(int type);
-void expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
-u16 get_service_set(struct v4l2_sliced_vbi_format *fmt);
+u16 ivtv_service2vbi(int type);
+void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
+u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt);
int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg);
int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg);
diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/video/ivtv/ivtv-queue.c
index 3e1deec..fc8b1ea 100644
--- a/drivers/media/video/ivtv/ivtv-queue.c
+++ b/drivers/media/video/ivtv/ivtv-queue.c
@@ -203,14 +203,14 @@
s->dma != PCI_DMA_NONE ? "DMA " : "",
s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024);
- s->sg_pending = kzalloc(SGsize, GFP_KERNEL);
+ s->sg_pending = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN);
if (s->sg_pending == NULL) {
IVTV_ERR("Could not allocate sg_pending for %s stream\n", s->name);
return -ENOMEM;
}
s->sg_pending_size = 0;
- s->sg_processing = kzalloc(SGsize, GFP_KERNEL);
+ s->sg_processing = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN);
if (s->sg_processing == NULL) {
IVTV_ERR("Could not allocate sg_processing for %s stream\n", s->name);
kfree(s->sg_pending);
@@ -219,7 +219,8 @@
}
s->sg_processing_size = 0;
- s->sg_dma = kzalloc(sizeof(struct ivtv_sg_element), GFP_KERNEL);
+ s->sg_dma = kzalloc(sizeof(struct ivtv_sg_element),
+ GFP_KERNEL|__GFP_NOWARN);
if (s->sg_dma == NULL) {
IVTV_ERR("Could not allocate sg_dma for %s stream\n", s->name);
kfree(s->sg_pending);
@@ -235,11 +236,12 @@
/* allocate stream buffers. Initially all buffers are in q_free. */
for (i = 0; i < s->buffers; i++) {
- struct ivtv_buffer *buf = kzalloc(sizeof(struct ivtv_buffer), GFP_KERNEL);
+ struct ivtv_buffer *buf = kzalloc(sizeof(struct ivtv_buffer),
+ GFP_KERNEL|__GFP_NOWARN);
if (buf == NULL)
break;
- buf->buf = kmalloc(s->buf_size + 256, GFP_KERNEL);
+ buf->buf = kmalloc(s->buf_size + 256, GFP_KERNEL|__GFP_NOWARN);
if (buf->buf == NULL) {
kfree(buf);
break;
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 4ab8d36..c47c2b9 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -244,7 +244,7 @@
return 0;
/* One or more streams could not be initialized. Clean 'em all up. */
- ivtv_streams_cleanup(itv);
+ ivtv_streams_cleanup(itv, 0);
return -ENOMEM;
}
@@ -304,12 +304,12 @@
return 0;
/* One or more streams could not be initialized. Clean 'em all up. */
- ivtv_streams_cleanup(itv);
+ ivtv_streams_cleanup(itv, 1);
return -ENOMEM;
}
/* Unregister v4l2 devices */
-void ivtv_streams_cleanup(struct ivtv *itv)
+void ivtv_streams_cleanup(struct ivtv *itv, int unregister)
{
int type;
@@ -322,8 +322,11 @@
continue;
ivtv_stream_free(&itv->streams[type]);
- /* Unregister device */
- video_unregister_device(vdev);
+ /* Unregister or release device */
+ if (unregister)
+ video_unregister_device(vdev);
+ else
+ video_device_release(vdev);
}
}
diff --git a/drivers/media/video/ivtv/ivtv-streams.h b/drivers/media/video/ivtv/ivtv-streams.h
index 3d76a41..a653a51 100644
--- a/drivers/media/video/ivtv/ivtv-streams.h
+++ b/drivers/media/video/ivtv/ivtv-streams.h
@@ -23,7 +23,7 @@
int ivtv_streams_setup(struct ivtv *itv);
int ivtv_streams_register(struct ivtv *itv);
-void ivtv_streams_cleanup(struct ivtv *itv);
+void ivtv_streams_cleanup(struct ivtv *itv, int unregister);
/* Capture related */
int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s);
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
index c151bcf..71798f0 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/drivers/media/video/ivtv/ivtv-vbi.c
@@ -169,7 +169,8 @@
linemask[0] |= (1 << l);
else
linemask[1] |= (1 << (l - 32));
- dst[sd + 12 + line * 43] = service2vbi(itv->vbi.sliced_data[i].id);
+ dst[sd + 12 + line * 43] =
+ ivtv_service2vbi(itv->vbi.sliced_data[i].id);
memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42);
line++;
}
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index 62f70bd..a9417f6 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -908,7 +908,7 @@
}
/* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
- yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL);
+ yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL|__GFP_NOWARN);
if (yi->blanking_ptr) {
yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
} else {
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index df789f6..73be154 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -948,7 +948,8 @@
}
/* Allocate the pseudo palette */
- oi->ivtvfb_info.pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
+ oi->ivtvfb_info.pseudo_palette =
+ kmalloc(sizeof(u32) * 16, GFP_KERNEL|__GFP_NOWARN);
if (!oi->ivtvfb_info.pseudo_palette) {
IVTVFB_ERR("abort, unable to alloc pseudo pallete\n");
@@ -1056,7 +1057,8 @@
return -EBUSY;
}
- itv->osd_info = kzalloc(sizeof(struct osd_info), GFP_ATOMIC);
+ itv->osd_info = kzalloc(sizeof(struct osd_info),
+ GFP_ATOMIC|__GFP_NOWARN);
if (itv->osd_info == NULL) {
IVTVFB_ERR("Failed to allocate memory for osd_info\n");
return -ENOMEM;
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 179e470..ee43499 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -12,15 +12,12 @@
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/log2.h>
+#include <linux/gpio.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
#include <media/soc_camera.h>
-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
-#include <asm/gpio.h>
-#endif
-
/* mt9m001 i2c address 0x5d
* The platform has to define i2c_board_info
* and call i2c_register_board_info() */
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index d1391ac..1658fe5 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -13,15 +13,12 @@
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/log2.h>
+#include <linux/gpio.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
#include <media/soc_camera.h>
-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
-#include <asm/gpio.h>
-#endif
-
/* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
* The platform has to define i2c_board_info
* and call i2c_register_board_info() */
@@ -91,7 +88,7 @@
struct mt9v022 {
struct i2c_client *client;
struct soc_camera_device icd;
- int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
+ int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
int switch_gpio;
u16 chip_control;
unsigned char datawidth;
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig
index 9620c67..4482b2c 100644
--- a/drivers/media/video/pvrusb2/Kconfig
+++ b/drivers/media/video/pvrusb2/Kconfig
@@ -1,8 +1,10 @@
config VIDEO_PVRUSB2
tristate "Hauppauge WinTV-PVR USB2 support"
depends on VIDEO_V4L2 && I2C
+ depends on VIDEO_MEDIA # Avoids pvrusb = Y / DVB = M
+ depends on HOTPLUG # due to FW_LOADER
select FW_LOADER
- select MEDIA_TUNER
+ select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEO_CX2341X
select VIDEO_SAA711X
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index 40e4c3b..83f076a 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -3,7 +3,7 @@
depends on VIDEO_DEV && PCI && I2C && INPUT
select VIDEOBUF_DMA_SG
select VIDEO_IR
- select MEDIA_TUNER
+ select VIDEO_TUNER
select VIDEO_TVEEPROM
select CRC32
---help---
@@ -27,6 +27,7 @@
config VIDEO_SAA7134_DVB
tristate "DVB/ATSC Support for saa7134 based TV cards"
depends on VIDEO_SAA7134 && DVB_CORE
+ depends on HOTPLUG # due to FW_LOADER
select VIDEOBUF_DVB
select FW_LOADER
select DVB_PLL if !DVB_FE_CUSTOMISE
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index eec1278..2c19cd0 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -864,7 +864,6 @@
struct saa7134_dev *dev;
struct saa7134_mpeg_ops *mops;
int err;
- int mask;
if (saa7134_devcount == SAA7134_MAXBOARDS)
return -ENOMEM;
@@ -1065,11 +1064,6 @@
if (TUNER_ABSENT != dev->tuner_type)
saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
- if (card(dev).gpiomask != 0) {
- mask = card(dev).gpiomask;
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, 0);
- }
return 0;
fail4:
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 2d16be2..469f93a 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -538,19 +538,23 @@
return 0;
}
-static void configure_tda827x_fe(struct saa7134_dev *dev, struct tda1004x_config *cdec_conf,
- struct tda827x_config *tuner_conf)
+static int configure_tda827x_fe(struct saa7134_dev *dev,
+ struct tda1004x_config *cdec_conf,
+ struct tda827x_config *tuner_conf)
{
dev->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap);
if (dev->dvb.frontend) {
if (cdec_conf->i2c_gate)
dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
- if (dvb_attach(tda827x_attach, dev->dvb.frontend, cdec_conf->tuner_address,
- &dev->i2c_adap, tuner_conf) == NULL) {
- wprintk("no tda827x tuner found at addr: %02x\n",
+ if (dvb_attach(tda827x_attach, dev->dvb.frontend,
+ cdec_conf->tuner_address,
+ &dev->i2c_adap, tuner_conf))
+ return 0;
+
+ wprintk("no tda827x tuner found at addr: %02x\n",
cdec_conf->tuner_address);
- }
}
+ return -EINVAL;
}
/* ------------------------------------------------------------------ */
@@ -997,7 +1001,9 @@
break;
case SAA7134_BOARD_FLYDVBTDUO:
case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS:
- configure_tda827x_fe(dev, &tda827x_lifeview_config, &tda827x_cfg_0);
+ if (configure_tda827x_fe(dev, &tda827x_lifeview_config,
+ &tda827x_cfg_0) < 0)
+ goto dettach_frontend;
break;
case SAA7134_BOARD_PHILIPS_EUROPA:
case SAA7134_BOARD_VIDEOMATE_DVBT_300:
@@ -1022,36 +1028,52 @@
}
break;
case SAA7134_BOARD_KWORLD_DVBT_210:
- configure_tda827x_fe(dev, &kworld_dvb_t_210_config, &tda827x_cfg_2);
+ if (configure_tda827x_fe(dev, &kworld_dvb_t_210_config,
+ &tda827x_cfg_2) < 0)
+ goto dettach_frontend;
break;
case SAA7134_BOARD_PHILIPS_TIGER:
- configure_tda827x_fe(dev, &philips_tiger_config, &tda827x_cfg_0);
+ if (configure_tda827x_fe(dev, &philips_tiger_config,
+ &tda827x_cfg_0) < 0)
+ goto dettach_frontend;
break;
case SAA7134_BOARD_PINNACLE_PCTV_310i:
- configure_tda827x_fe(dev, &pinnacle_pctv_310i_config, &tda827x_cfg_1);
+ if (configure_tda827x_fe(dev, &pinnacle_pctv_310i_config,
+ &tda827x_cfg_1) < 0)
+ goto dettach_frontend;
break;
case SAA7134_BOARD_HAUPPAUGE_HVR1110:
- configure_tda827x_fe(dev, &hauppauge_hvr_1110_config, &tda827x_cfg_1);
+ if (configure_tda827x_fe(dev, &hauppauge_hvr_1110_config,
+ &tda827x_cfg_1) < 0)
+ goto dettach_frontend;
break;
case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
- configure_tda827x_fe(dev, &asus_p7131_dual_config, &tda827x_cfg_0);
+ if (configure_tda827x_fe(dev, &asus_p7131_dual_config,
+ &tda827x_cfg_0) < 0)
+ goto dettach_frontend;
break;
case SAA7134_BOARD_FLYDVBT_LR301:
- configure_tda827x_fe(dev, &tda827x_lifeview_config, &tda827x_cfg_0);
+ if (configure_tda827x_fe(dev, &tda827x_lifeview_config,
+ &tda827x_cfg_0) < 0)
+ goto dettach_frontend;
break;
case SAA7134_BOARD_FLYDVB_TRIO:
- if(! use_frontend) { /* terrestrial */
- configure_tda827x_fe(dev, &lifeview_trio_config, &tda827x_cfg_0);
+ if (!use_frontend) { /* terrestrial */
+ if (configure_tda827x_fe(dev, &lifeview_trio_config,
+ &tda827x_cfg_0) < 0)
+ goto dettach_frontend;
} else { /* satellite */
dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
if (dev->dvb.frontend) {
if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63,
&dev->i2c_adap, 0) == NULL) {
wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__);
+ goto dettach_frontend;
}
if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap,
0x08, 0, 0) == NULL) {
wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__);
+ goto dettach_frontend;
}
}
}
@@ -1067,15 +1089,20 @@
&ads_duo_cfg) == NULL) {
wprintk("no tda827x tuner found at addr: %02x\n",
ads_tech_duo_config.tuner_address);
+ goto dettach_frontend;
}
}
break;
case SAA7134_BOARD_TEVION_DVBT_220RF:
- configure_tda827x_fe(dev, &tevion_dvbt220rf_config, &tda827x_cfg_0);
+ if (configure_tda827x_fe(dev, &tevion_dvbt220rf_config,
+ &tda827x_cfg_0) < 0)
+ goto dettach_frontend;
break;
case SAA7134_BOARD_MEDION_MD8800_QUADRO:
if (!use_frontend) { /* terrestrial */
- configure_tda827x_fe(dev, &md8800_dvbt_config, &tda827x_cfg_0);
+ if (configure_tda827x_fe(dev, &md8800_dvbt_config,
+ &tda827x_cfg_0) < 0)
+ goto dettach_frontend;
} else { /* satellite */
dev->dvb.frontend = dvb_attach(tda10086_attach,
&flydvbs, &dev->i2c_adap);
@@ -1086,16 +1113,20 @@
struct i2c_msg msg = {.addr = 0x08, .flags = 0, .len = 1};
if (dvb_attach(tda826x_attach, dev->dvb.frontend,
- 0x60, &dev->i2c_adap, 0) == NULL)
+ 0x60, &dev->i2c_adap, 0) == NULL) {
wprintk("%s: Medion Quadro, no tda826x "
"found !\n", __func__);
+ goto dettach_frontend;
+ }
if (dev_id != 0x08) {
/* we need to open the i2c gate (we know it exists) */
fe->ops.i2c_gate_ctrl(fe, 1);
if (dvb_attach(isl6405_attach, fe,
- &dev->i2c_adap, 0x08, 0, 0) == NULL)
+ &dev->i2c_adap, 0x08, 0, 0) == NULL) {
wprintk("%s: Medion Quadro, no ISL6405 "
"found !\n", __func__);
+ goto dettach_frontend;
+ }
if (dev_id == 0x07) {
/* fire up the 2nd section of the LNB supply since
we can't do this from the other section */
@@ -1117,19 +1148,17 @@
case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
dev->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
+ if (dev->dvb.frontend)
dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
NULL, DVB_PLL_TDHU2);
- }
break;
case SAA7134_BOARD_KWORLD_ATSC110:
dev->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
+ if (dev->dvb.frontend)
dvb_attach(simple_tuner_attach, dev->dvb.frontend,
&dev->i2c_adap, 0x61,
TUNER_PHILIPS_TUV1236D);
- }
break;
case SAA7134_BOARD_FLYDVBS_LR300:
dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
@@ -1138,10 +1167,12 @@
if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
&dev->i2c_adap, 0) == NULL) {
wprintk("%s: No tda826x found!\n", __func__);
+ goto dettach_frontend;
}
if (dvb_attach(isl6421_attach, dev->dvb.frontend,
&dev->i2c_adap, 0x08, 0, 0) == NULL) {
wprintk("%s: No ISL6421 found!\n", __func__);
+ goto dettach_frontend;
}
}
break;
@@ -1168,43 +1199,65 @@
}
break;
case SAA7134_BOARD_CINERGY_HT_PCMCIA:
- configure_tda827x_fe(dev, &cinergy_ht_config, &tda827x_cfg_0);
+ if (configure_tda827x_fe(dev, &cinergy_ht_config,
+ &tda827x_cfg_0) < 0)
+ goto dettach_frontend;
break;
case SAA7134_BOARD_CINERGY_HT_PCI:
- configure_tda827x_fe(dev, &cinergy_ht_pci_config, &tda827x_cfg_0);
+ if (configure_tda827x_fe(dev, &cinergy_ht_pci_config,
+ &tda827x_cfg_0) < 0)
+ goto dettach_frontend;
break;
case SAA7134_BOARD_PHILIPS_TIGER_S:
- configure_tda827x_fe(dev, &philips_tiger_s_config, &tda827x_cfg_2);
+ if (configure_tda827x_fe(dev, &philips_tiger_s_config,
+ &tda827x_cfg_2) < 0)
+ goto dettach_frontend;
break;
case SAA7134_BOARD_ASUS_P7131_4871:
- configure_tda827x_fe(dev, &asus_p7131_4871_config, &tda827x_cfg_2);
+ if (configure_tda827x_fe(dev, &asus_p7131_4871_config,
+ &tda827x_cfg_2) < 0)
+ goto dettach_frontend;
break;
case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
- configure_tda827x_fe(dev, &asus_p7131_hybrid_lna_config, &tda827x_cfg_2);
+ if (configure_tda827x_fe(dev, &asus_p7131_hybrid_lna_config,
+ &tda827x_cfg_2) < 0)
+ goto dettach_frontend;
break;
case SAA7134_BOARD_AVERMEDIA_SUPER_007:
- configure_tda827x_fe(dev, &avermedia_super_007_config, &tda827x_cfg_0);
+ if (configure_tda827x_fe(dev, &avermedia_super_007_config,
+ &tda827x_cfg_0) < 0)
+ goto dettach_frontend;
break;
case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
- configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config, &tda827x_cfg_2_sw42);
+ if (configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config,
+ &tda827x_cfg_2_sw42) < 0)
+ goto dettach_frontend;
break;
case SAA7134_BOARD_PHILIPS_SNAKE:
dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
&dev->i2c_adap);
if (dev->dvb.frontend) {
if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
- &dev->i2c_adap, 0) == NULL)
+ &dev->i2c_adap, 0) == NULL) {
wprintk("%s: No tda826x found!\n", __func__);
+ goto dettach_frontend;
+ }
if (dvb_attach(lnbp21_attach, dev->dvb.frontend,
- &dev->i2c_adap, 0, 0) == NULL)
+ &dev->i2c_adap, 0, 0) == NULL) {
wprintk("%s: No lnbp21 found!\n", __func__);
+ goto dettach_frontend;
+ }
}
break;
case SAA7134_BOARD_CREATIX_CTX953:
- configure_tda827x_fe(dev, &md8800_dvbt_config, &tda827x_cfg_0);
+ if (configure_tda827x_fe(dev, &md8800_dvbt_config,
+ &tda827x_cfg_0) < 0)
+ goto dettach_frontend;
break;
case SAA7134_BOARD_MSI_TVANYWHERE_AD11:
- configure_tda827x_fe(dev, &philips_tiger_s_config, &tda827x_cfg_2);
+ if (configure_tda827x_fe(dev, &philips_tiger_s_config,
+ &tda827x_cfg_2) < 0)
+ goto dettach_frontend;
break;
case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
dev->dvb.frontend = dvb_attach(mt352_attach,
@@ -1218,16 +1271,20 @@
if (dev->dvb.frontend) {
struct dvb_frontend *fe;
if (dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
- &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL)
+ &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) {
wprintk("%s: MD7134 DVB-S, no SD1878 "
"found !\n", __func__);
+ goto dettach_frontend;
+ }
/* we need to open the i2c gate (we know it exists) */
fe = dev->dvb.frontend;
fe->ops.i2c_gate_ctrl(fe, 1);
if (dvb_attach(isl6405_attach, fe,
- &dev->i2c_adap, 0x08, 0, 0) == NULL)
+ &dev->i2c_adap, 0x08, 0, 0) == NULL) {
wprintk("%s: MD7134 DVB-S, no ISL6405 "
"found !\n", __func__);
+ goto dettach_frontend;
+ }
fe->ops.i2c_gate_ctrl(fe, 0);
dev->original_set_voltage = fe->ops.set_voltage;
fe->ops.set_voltage = md8800_set_voltage;
@@ -1254,10 +1311,7 @@
if (!fe) {
printk(KERN_ERR "%s/2: xc3028 attach failed\n",
dev->name);
- dvb_frontend_detach(dev->dvb.frontend);
- dvb_unregister_frontend(dev->dvb.frontend);
- dev->dvb.frontend = NULL;
- return -1;
+ goto dettach_frontend;
}
}
@@ -1282,6 +1336,12 @@
dev->dvb.frontend->ops.tuner_ops.sleep(dev->dvb.frontend);
}
return ret;
+
+dettach_frontend:
+ dvb_frontend_detach(dev->dvb.frontend);
+ dev->dvb.frontend = NULL;
+
+ return -1;
}
static int dvb_fini(struct saa7134_dev *dev)
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index 9276ed9..b12c60c 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -30,6 +30,7 @@
#include <linux/kref.h>
#include <linux/usb.h>
+#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
@@ -245,6 +246,8 @@
return -1;
}
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+
/* sysfs functions */
/*FIXME cleanup this */
@@ -350,6 +353,10 @@
video_device_remove_file(vdev, &dev_attr_vflip);
}
+#else
+#define stk_create_sysfs_files(a)
+#define stk_remove_sysfs_files(a)
+#endif
/* *********************************************** */
/*
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 6bf104e..5a75788 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -40,11 +40,11 @@
typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
if (__a) { \
__r = (int) __a(ARGS); \
+ symbol_put(FUNCTION); \
} else { \
printk(KERN_ERR "TUNER: Unable to find " \
"symbol "#FUNCTION"()\n"); \
} \
- symbol_put(FUNCTION); \
__r; \
})
@@ -340,16 +340,6 @@
tuner_warn("====================== WARNING! ======================\n");
}
-static void attach_tda829x(struct tuner *t)
-{
- struct tda829x_config cfg = {
- .lna_cfg = t->config,
- .tuner_callback = t->tuner_callback,
- };
- dvb_attach(tda829x_attach,
- &t->fe, t->i2c->adapter, t->i2c->addr, &cfg);
-}
-
static struct xc5000_config xc5000_cfg;
static void set_type(struct i2c_client *c, unsigned int type,
@@ -385,12 +375,19 @@
switch (t->type) {
case TUNER_MT2032:
- dvb_attach(microtune_attach,
- &t->fe, t->i2c->adapter, t->i2c->addr);
+ if (!dvb_attach(microtune_attach,
+ &t->fe, t->i2c->adapter, t->i2c->addr))
+ goto attach_failed;
break;
case TUNER_PHILIPS_TDA8290:
{
- attach_tda829x(t);
+ struct tda829x_config cfg = {
+ .lna_cfg = t->config,
+ .tuner_callback = t->tuner_callback,
+ };
+ if (!dvb_attach(tda829x_attach, &t->fe, t->i2c->adapter,
+ t->i2c->addr, &cfg))
+ goto attach_failed;
break;
}
case TUNER_TEA5767:
@@ -441,8 +438,9 @@
break;
}
case TUNER_TDA9887:
- dvb_attach(tda9887_attach,
- &t->fe, t->i2c->adapter, t->i2c->addr);
+ if (!dvb_attach(tda9887_attach,
+ &t->fe, t->i2c->adapter, t->i2c->addr))
+ goto attach_failed;
break;
case TUNER_XC5000:
{
@@ -450,10 +448,10 @@
xc5000_cfg.i2c_address = t->i2c->addr;
xc5000_cfg.if_khz = 5380;
- xc5000_cfg.priv = c->adapter->algo_data;
xc5000_cfg.tuner_callback = t->tuner_callback;
if (!dvb_attach(xc5000_attach,
- &t->fe, t->i2c->adapter, &xc5000_cfg))
+ &t->fe, t->i2c->adapter, &xc5000_cfg,
+ c->adapter->algo_data))
goto attach_failed;
xc_tuner_ops = &t->fe.ops.tuner_ops;
@@ -1167,7 +1165,7 @@
/* If chip is not tda8290, don't register.
since it can be tda9887*/
if (tuner_symbol_probe(tda829x_probe, t->i2c->adapter,
- t->i2c->addr) == 0) {
+ t->i2c->addr) >= 0) {
tuner_dbg("tda829x detected\n");
} else {
/* Default is being tda9887 */
@@ -1181,7 +1179,7 @@
case 0x60:
if (tuner_symbol_probe(tea5767_autodetection,
t->i2c->adapter, t->i2c->addr)
- != EINVAL) {
+ >= 0) {
t->type = TUNER_TEA5767;
t->mode_mask = T_RADIO;
t->mode = T_STANDBY;
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 3cf8a8e..9da0e18 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -319,10 +319,12 @@
{AUDIO_CHIP_INTERNAL, "CX25843"},
{AUDIO_CHIP_INTERNAL, "CX23418"},
{AUDIO_CHIP_INTERNAL, "CX23885"},
- /* 40-42 */
+ /* 40-44 */
{AUDIO_CHIP_INTERNAL, "CX23888"},
{AUDIO_CHIP_INTERNAL, "SAA7131"},
{AUDIO_CHIP_INTERNAL, "CX23887"},
+ {AUDIO_CHIP_INTERNAL, "SAA7164"},
+ {AUDIO_CHIP_INTERNAL, "AU8522"},
};
/* This list is supplied by Hauppauge. Thanks! */
@@ -341,8 +343,10 @@
"CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
/* 30-34 */
"CX25843", "CX23418", "NEC61153", "CX23885", "CX23888",
- /* 35-37 */
- "SAA7131", "CX25837", "CX23887"
+ /* 35-39 */
+ "SAA7131", "CX25837", "CX23887", "CX23885A", "CX23887A",
+ /* 40-42 */
+ "SAA7164", "CX23885B", "AU8522"
};
static int hasRadioTuner(int tunerType)
diff --git a/drivers/media/video/usbvision/Kconfig b/drivers/media/video/usbvision/Kconfig
index 74e1d30..fc24ef0 100644
--- a/drivers/media/video/usbvision/Kconfig
+++ b/drivers/media/video/usbvision/Kconfig
@@ -1,7 +1,7 @@
config VIDEO_USBVISION
tristate "USB video devices based on Nogatech NT1003/1004/1005"
depends on I2C && VIDEO_V4L2
- select MEDIA_TUNER
+ select VIDEO_TUNER
select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
---help---
There are more than 50 different USB video devices based on