help
          Say Y here to include support for the MT2032 / MT2050 tuner.
 
+config DVB_TUNER_MT2060
+       tristate "Microtune MT2060 silicon IF tuner"
+       depends on I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A driver for the silicon IF tuner MT2060 from Microtune.
+
+config DVB_TUNER_MT2266
+       tristate "Microtune MT2266 silicon tuner"
+       depends on I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A driver for the silicon baseband tuner MT2266 from Microtune.
+
+config DVB_TUNER_MT2131
+       tristate "Microtune MT2131 silicon tuner"
+       depends on I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A driver for the silicon baseband tuner MT2131 from Microtune.
+
+config DVB_TUNER_QT1010
+       tristate "Quantek QT1010 silicon tuner"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A driver for the silicon tuner QT1010 from Quantek.
+
 config TUNER_XC2028
        tristate "XCeive xc2028/xc3028 tuners"
        depends on I2C && FW_LOADER
 
 obj-$(CONFIG_DVB_TDA827X) += tda827x.o
 obj-$(CONFIG_DVB_TDA18271) += tda18271.o
 obj-$(CONFIG_DVB_TUNER_XC5000) += xc5000.o
+obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o
+obj-$(CONFIG_DVB_TUNER_MT2266) += mt2266.o
+obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o
+obj-$(CONFIG_DVB_TUNER_MT2131) += mt2131.o
 
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
 
--- /dev/null
+/*
+ *  Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
+ *
+ *  Copyright (c) 2006 Olivier DANET <odanet@caramail.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+/* In that file, frequencies are expressed in kiloHertz to avoid 32 bits overflows */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+
+#include "mt2060.h"
+#include "mt2060_priv.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+#define dprintk(args...) do { if (debug) {printk(KERN_DEBUG "MT2060: " args); printk("\n"); }} while (0)
+
+// Reads a single register
+static int mt2060_readreg(struct mt2060_priv *priv, u8 reg, u8 *val)
+{
+       struct i2c_msg msg[2] = {
+               { .addr = priv->cfg->i2c_address, .flags = 0,        .buf = ®, .len = 1 },
+               { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val,  .len = 1 },
+       };
+
+       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
+               printk(KERN_WARNING "mt2060 I2C read failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+// Writes a single register
+static int mt2060_writereg(struct mt2060_priv *priv, u8 reg, u8 val)
+{
+       u8 buf[2] = { reg, val };
+       struct i2c_msg msg = {
+               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2
+       };
+
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "mt2060 I2C write failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+// Writes a set of consecutive registers
+static int mt2060_writeregs(struct mt2060_priv *priv,u8 *buf, u8 len)
+{
+       struct i2c_msg msg = {
+               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = len
+       };
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "mt2060 I2C write failed (len=%i)\n",(int)len);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+// Initialisation sequences
+// LNABAND=3, NUM1=0x3C, DIV1=0x74, NUM2=0x1080, DIV2=0x49
+static u8 mt2060_config1[] = {
+       REG_LO1C1,
+       0x3F,   0x74,   0x00,   0x08,   0x93
+};
+
+// FMCG=2, GP2=0, GP1=0
+static u8 mt2060_config2[] = {
+       REG_MISC_CTRL,
+       0x20,   0x1E,   0x30,   0xff,   0x80,   0xff,   0x00,   0x2c,   0x42
+};
+
+//  VGAG=3, V1CSE=1
+
+#ifdef  MT2060_SPURCHECK
+/* The function below calculates the frequency offset between the output frequency if2
+ and the closer cross modulation subcarrier between lo1 and lo2 up to the tenth harmonic */
+static int mt2060_spurcalc(u32 lo1,u32 lo2,u32 if2)
+{
+       int I,J;
+       int dia,diamin,diff;
+       diamin=1000000;
+       for (I = 1; I < 10; I++) {
+               J = ((2*I*lo1)/lo2+1)/2;
+               diff = I*(int)lo1-J*(int)lo2;
+               if (diff < 0) diff=-diff;
+               dia = (diff-(int)if2);
+               if (dia < 0) dia=-dia;
+               if (diamin > dia) diamin=dia;
+       }
+       return diamin;
+}
+
+#define BANDWIDTH 4000 // kHz
+
+/* Calculates the frequency offset to add to avoid spurs. Returns 0 if no offset is needed */
+static int mt2060_spurcheck(u32 lo1,u32 lo2,u32 if2)
+{
+       u32 Spur,Sp1,Sp2;
+       int I,J;
+       I=0;
+       J=1000;
+
+       Spur=mt2060_spurcalc(lo1,lo2,if2);
+       if (Spur < BANDWIDTH) {
+               /* Potential spurs detected */
+               dprintk("Spurs before : f_lo1: %d  f_lo2: %d  (kHz)",
+                       (int)lo1,(int)lo2);
+               I=1000;
+               Sp1 = mt2060_spurcalc(lo1+I,lo2+I,if2);
+               Sp2 = mt2060_spurcalc(lo1-I,lo2-I,if2);
+
+               if (Sp1 < Sp2) {
+                       J=-J; I=-I; Spur=Sp2;
+               } else
+                       Spur=Sp1;
+
+               while (Spur < BANDWIDTH) {
+                       I += J;
+                       Spur = mt2060_spurcalc(lo1+I,lo2+I,if2);
+               }
+               dprintk("Spurs after  : f_lo1: %d  f_lo2: %d  (kHz)",
+                       (int)(lo1+I),(int)(lo2+I));
+       }
+       return I;
+}
+#endif
+
+#define IF2  36150       // IF2 frequency = 36.150 MHz
+#define FREF 16000       // Quartz oscillator 16 MHz
+
+static int mt2060_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+       struct mt2060_priv *priv;
+       int ret=0;
+       int i=0;
+       u32 freq;
+       u8  lnaband;
+       u32 f_lo1,f_lo2;
+       u32 div1,num1,div2,num2;
+       u8  b[8];
+       u32 if1;
+
+       priv = fe->tuner_priv;
+
+       if1 = priv->if1_freq;
+       b[0] = REG_LO1B1;
+       b[1] = 0xFF;
+
+       mt2060_writeregs(priv,b,2);
+
+       freq = params->frequency / 1000; // Hz -> kHz
+       priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
+
+       f_lo1 = freq + if1 * 1000;
+       f_lo1 = (f_lo1 / 250) * 250;
+       f_lo2 = f_lo1 - freq - IF2;
+       // From the Comtech datasheet, the step used is 50kHz. The tuner chip could be more precise
+       f_lo2 = ((f_lo2 + 25) / 50) * 50;
+       priv->frequency =  (f_lo1 - f_lo2 - IF2) * 1000,
+
+#ifdef MT2060_SPURCHECK
+       // LO-related spurs detection and correction
+       num1   = mt2060_spurcheck(f_lo1,f_lo2,IF2);
+       f_lo1 += num1;
+       f_lo2 += num1;
+#endif
+       //Frequency LO1 = 16MHz * (DIV1 + NUM1/64 )
+       num1 = f_lo1 / (FREF / 64);
+       div1 = num1 / 64;
+       num1 &= 0x3f;
+
+       // Frequency LO2 = 16MHz * (DIV2 + NUM2/8192 )
+       num2 = f_lo2 * 64 / (FREF / 128);
+       div2 = num2 / 8192;
+       num2 &= 0x1fff;
+
+       if (freq <=  95000) lnaband = 0xB0; else
+       if (freq <= 180000) lnaband = 0xA0; else
+       if (freq <= 260000) lnaband = 0x90; else
+       if (freq <= 335000) lnaband = 0x80; else
+       if (freq <= 425000) lnaband = 0x70; else
+       if (freq <= 480000) lnaband = 0x60; else
+       if (freq <= 570000) lnaband = 0x50; else
+       if (freq <= 645000) lnaband = 0x40; else
+       if (freq <= 730000) lnaband = 0x30; else
+       if (freq <= 810000) lnaband = 0x20; else lnaband = 0x10;
+
+       b[0] = REG_LO1C1;
+       b[1] = lnaband | ((num1 >>2) & 0x0F);
+       b[2] = div1;
+       b[3] = (num2 & 0x0F)  | ((num1 & 3) << 4);
+       b[4] = num2 >> 4;
+       b[5] = ((num2 >>12) & 1) | (div2 << 1);
+
+       dprintk("IF1: %dMHz",(int)if1);
+       dprintk("PLL freq=%dkHz  f_lo1=%dkHz  f_lo2=%dkHz",(int)freq,(int)f_lo1,(int)f_lo2);
+       dprintk("PLL div1=%d  num1=%d  div2=%d  num2=%d",(int)div1,(int)num1,(int)div2,(int)num2);
+       dprintk("PLL [1..5]: %2x %2x %2x %2x %2x",(int)b[1],(int)b[2],(int)b[3],(int)b[4],(int)b[5]);
+
+       mt2060_writeregs(priv,b,6);
+
+       //Waits for pll lock or timeout
+       i = 0;
+       do {
+               mt2060_readreg(priv,REG_LO_STATUS,b);
+               if ((b[0] & 0x88)==0x88)
+                       break;
+               msleep(4);
+               i++;
+       } while (i<10);
+
+       return ret;
+}
+
+static void mt2060_calibrate(struct mt2060_priv *priv)
+{
+       u8 b = 0;
+       int i = 0;
+
+       if (mt2060_writeregs(priv,mt2060_config1,sizeof(mt2060_config1)))
+               return;
+       if (mt2060_writeregs(priv,mt2060_config2,sizeof(mt2060_config2)))
+               return;
+
+       /* initialize the clock output */
+       mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x30);
+
+       do {
+               b |= (1 << 6); // FM1SS;
+               mt2060_writereg(priv, REG_LO2C1,b);
+               msleep(20);
+
+               if (i == 0) {
+                       b |= (1 << 7); // FM1CA;
+                       mt2060_writereg(priv, REG_LO2C1,b);
+                       b &= ~(1 << 7); // FM1CA;
+                       msleep(20);
+               }
+
+               b &= ~(1 << 6); // FM1SS
+               mt2060_writereg(priv, REG_LO2C1,b);
+
+               msleep(20);
+               i++;
+       } while (i < 9);
+
+       i = 0;
+       while (i++ < 10 && mt2060_readreg(priv, REG_MISC_STAT, &b) == 0 && (b & (1 << 6)) == 0)
+               msleep(20);
+
+       if (i < 10) {
+               mt2060_readreg(priv, REG_FM_FREQ, &priv->fmfreq); // now find out, what is fmreq used for :)
+               dprintk("calibration was successful: %d", (int)priv->fmfreq);
+       } else
+               dprintk("FMCAL timed out");
+}
+
+static int mt2060_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct mt2060_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static int mt2060_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct mt2060_priv *priv = fe->tuner_priv;
+       *bandwidth = priv->bandwidth;
+       return 0;
+}
+
+static int mt2060_init(struct dvb_frontend *fe)
+{
+       struct mt2060_priv *priv = fe->tuner_priv;
+       return mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x33);
+}
+
+static int mt2060_sleep(struct dvb_frontend *fe)
+{
+       struct mt2060_priv *priv = fe->tuner_priv;
+       return mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x30);
+}
+
+static int mt2060_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static const struct dvb_tuner_ops mt2060_tuner_ops = {
+       .info = {
+               .name           = "Microtune MT2060",
+               .frequency_min  =  48000000,
+               .frequency_max  = 860000000,
+               .frequency_step =     50000,
+       },
+
+       .release       = mt2060_release,
+
+       .init          = mt2060_init,
+       .sleep         = mt2060_sleep,
+
+       .set_params    = mt2060_set_params,
+       .get_frequency = mt2060_get_frequency,
+       .get_bandwidth = mt2060_get_bandwidth
+};
+
+/* This functions tries to identify a MT2060 tuner by reading the PART/REV register. This is hasty. */
+struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
+{
+       struct mt2060_priv *priv = NULL;
+       u8 id = 0;
+
+       priv = kzalloc(sizeof(struct mt2060_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->cfg      = cfg;
+       priv->i2c      = i2c;
+       priv->if1_freq = if1;
+
+       if (mt2060_readreg(priv,REG_PART_REV,&id) != 0) {
+               kfree(priv);
+               return NULL;
+       }
+
+       if (id != PART_REV) {
+               kfree(priv);
+               return NULL;
+       }
+       printk(KERN_INFO "MT2060: successfully identified (IF1 = %d)\n", if1);
+       memcpy(&fe->ops.tuner_ops, &mt2060_tuner_ops, sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = priv;
+
+       mt2060_calibrate(priv);
+
+       return fe;
+}
+EXPORT_SYMBOL(mt2060_attach);
+
+MODULE_AUTHOR("Olivier DANET");
+MODULE_DESCRIPTION("Microtune MT2060 silicon tuner driver");
+MODULE_LICENSE("GPL");
 
--- /dev/null
+/*
+ *  Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
+ *
+ *  Copyright (c) 2006 Olivier DANET <odanet@caramail.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef MT2060_H
+#define MT2060_H
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct mt2060_config {
+       u8 i2c_address;
+       u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
+};
+
+#if defined(CONFIG_DVB_TUNER_MT2060) || (defined(CONFIG_DVB_TUNER_MT2060_MODULE) && defined(MODULE))
+extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1);
+#else
+static inline struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_TUNER_MT2060
+
+#endif
 
--- /dev/null
+/*
+ *  Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
+ *
+ *  Copyright (c) 2006 Olivier DANET <odanet@caramail.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef MT2060_PRIV_H
+#define MT2060_PRIV_H
+
+// Uncomment the #define below to enable spurs checking. The results where quite unconvincing.
+// #define MT2060_SPURCHECK
+
+/* This driver is based on the information available in the datasheet of the
+   "Comtech SDVBT-3K6M" tuner ( K1000737843.pdf ) which features the MT2060 register map :
+
+   I2C Address : 0x60
+
+   Reg.No |   B7   |   B6   |   B5   |   B4   |   B3   |   B2   |   B1   |   B0   | ( defaults )
+   --------------------------------------------------------------------------------
+       00 | [              PART             ] | [              REV              ] | R  = 0x63
+       01 | [             LNABAND           ] | [              NUM1(5:2)        ] | RW = 0x3F
+       02 | [                               DIV1                                ] | RW = 0x74
+       03 | FM1CA  | FM1SS  | [  NUM1(1:0)  ] | [              NUM2(3:0)        ] | RW = 0x00
+       04 |                                 NUM2(11:4)                          ] | RW = 0x08
+       05 | [                               DIV2                       ] |NUM2(12)| RW = 0x93
+       06 | L1LK   | [        TAD1          ] | L2LK   | [         TAD2         ] | R
+       07 | [                               FMF                                 ] | R
+       08 |   ?    | FMCAL  |   ?    |   ?    |   ?    |   ?    |   ?    | TEMP   | R
+       09 |   0    |   0    | [    FMGC     ] |   0    | GP02   | GP01   |   0    | RW = 0x20
+       0A | ??
+       0B |   0    |   0    |   1    |   1    |   0    |   0    | [   VGAG      ] | RW = 0x30
+       0C | V1CSE  |   1    |   1    |   1    |   1    |   1    |   1    |   1    | RW = 0xFF
+       0D |   1    |   0    | [                      V1CS                       ] | RW = 0xB0
+       0E | ??
+       0F | ??
+       10 | ??
+       11 | [             LOTO              ] |   0    |   0    |   1    |   0    | RW = 0x42
+
+       PART    : Part code      : 6 for MT2060
+       REV     : Revision code  : 3 for current revision
+       LNABAND : Input frequency range : ( See code for details )
+       NUM1 / DIV1 / NUM2 / DIV2 : Frequencies programming ( See code for details )
+       FM1CA  : Calibration Start Bit
+       FM1SS  : Calibration Single Step bit
+       L1LK   : LO1 Lock Detect
+       TAD1   : Tune Line ADC ( ? )
+       L2LK   : LO2 Lock Detect
+       TAD2   : Tune Line ADC ( ? )
+       FMF    : Estimated first IF Center frequency Offset ( ? )
+       FM1CAL : Calibration done bit
+       TEMP   : On chip temperature sensor
+       FMCG   : Mixer 1 Cap Gain ( ? )
+       GP01 / GP02 : Programmable digital outputs. Unconnected pins ?
+       V1CSE  : LO1 VCO Automatic Capacitor Select Enable ( ? )
+       V1CS   : LO1 Capacitor Selection Value ( ? )
+       LOTO   : LO Timeout ( ? )
+       VGAG   : Tuner Output gain
+*/
+
+#define I2C_ADDRESS 0x60
+
+#define REG_PART_REV   0
+#define REG_LO1C1      1
+#define REG_LO1C2      2
+#define REG_LO2C1      3
+#define REG_LO2C2      4
+#define REG_LO2C3      5
+#define REG_LO_STATUS  6
+#define REG_FM_FREQ    7
+#define REG_MISC_STAT  8
+#define REG_MISC_CTRL  9
+#define REG_RESERVED_A 0x0A
+#define REG_VGAG       0x0B
+#define REG_LO1B1      0x0C
+#define REG_LO1B2      0x0D
+#define REG_LOTO       0x11
+
+#define PART_REV 0x63 // The current driver works only with PART=6 and REV=3 chips
+
+struct mt2060_priv {
+       struct mt2060_config *cfg;
+       struct i2c_adapter   *i2c;
+
+       u32 frequency;
+       u32 bandwidth;
+       u16 if1_freq;
+       u8  fmfreq;
+};
+
+#endif
 
--- /dev/null
+/*
+ *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
+ *
+ *  Copyright (c) 2006 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.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+
+#include "mt2131.h"
+#include "mt2131_priv.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+#define dprintk(level,fmt, arg...) if (debug >= level) \
+       printk(KERN_INFO "%s: " fmt, "mt2131", ## arg)
+
+static u8 mt2131_config1[] = {
+       0x01,
+       0x50, 0x00, 0x50, 0x80, 0x00, 0x49, 0xfa, 0x88,
+       0x08, 0x77, 0x41, 0x04, 0x00, 0x00, 0x00, 0x32,
+       0x7f, 0xda, 0x4c, 0x00, 0x10, 0xaa, 0x78, 0x80,
+       0xff, 0x68, 0xa0, 0xff, 0xdd, 0x00, 0x00
+};
+
+static u8 mt2131_config2[] = {
+       0x10,
+       0x7f, 0xc8, 0x0a, 0x5f, 0x00, 0x04
+};
+
+static int mt2131_readreg(struct mt2131_priv *priv, u8 reg, u8 *val)
+{
+       struct i2c_msg msg[2] = {
+               { .addr = priv->cfg->i2c_address, .flags = 0,
+                 .buf = ®, .len = 1 },
+               { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
+                 .buf = val,  .len = 1 },
+       };
+
+       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
+               printk(KERN_WARNING "mt2131 I2C read failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int mt2131_writereg(struct mt2131_priv *priv, u8 reg, u8 val)
+{
+       u8 buf[2] = { reg, val };
+       struct i2c_msg msg = { .addr = priv->cfg->i2c_address, .flags = 0,
+                              .buf = buf, .len = 2 };
+
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "mt2131 I2C write failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int mt2131_writeregs(struct mt2131_priv *priv,u8 *buf, u8 len)
+{
+       struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
+                              .flags = 0, .buf = buf, .len = len };
+
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "mt2131 I2C write failed (len=%i)\n",
+                      (int)len);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int mt2131_set_params(struct dvb_frontend *fe,
+                            struct dvb_frontend_parameters *params)
+{
+       struct mt2131_priv *priv;
+       int ret=0, i;
+       u32 freq;
+       u8  if_band_center;
+       u32 f_lo1, f_lo2;
+       u32 div1, num1, div2, num2;
+       u8  b[8];
+       u8 lockval = 0;
+
+       priv = fe->tuner_priv;
+       if (fe->ops.info.type == FE_OFDM)
+               priv->bandwidth = params->u.ofdm.bandwidth;
+       else
+               priv->bandwidth = 0;
+
+       freq = params->frequency / 1000;  // Hz -> kHz
+       dprintk(1, "%s() freq=%d\n", __func__, freq);
+
+       f_lo1 = freq + MT2131_IF1 * 1000;
+       f_lo1 = (f_lo1 / 250) * 250;
+       f_lo2 = f_lo1 - freq - MT2131_IF2;
+
+       priv->frequency =  (f_lo1 - f_lo2 - MT2131_IF2) * 1000;
+
+       /* Frequency LO1 = 16MHz * (DIV1 + NUM1/8192 ) */
+       num1 = f_lo1 * 64 / (MT2131_FREF / 128);
+       div1 = num1 / 8192;
+       num1 &= 0x1fff;
+
+       /* Frequency LO2 = 16MHz * (DIV2 + NUM2/8192 ) */
+       num2 = f_lo2 * 64 / (MT2131_FREF / 128);
+       div2 = num2 / 8192;
+       num2 &= 0x1fff;
+
+       if (freq <=   82500) if_band_center = 0x00; else
+       if (freq <=  137500) if_band_center = 0x01; else
+       if (freq <=  192500) if_band_center = 0x02; else
+       if (freq <=  247500) if_band_center = 0x03; else
+       if (freq <=  302500) if_band_center = 0x04; else
+       if (freq <=  357500) if_band_center = 0x05; else
+       if (freq <=  412500) if_band_center = 0x06; else
+       if (freq <=  467500) if_band_center = 0x07; else
+       if (freq <=  522500) if_band_center = 0x08; else
+       if (freq <=  577500) if_band_center = 0x09; else
+       if (freq <=  632500) if_band_center = 0x0A; else
+       if (freq <=  687500) if_band_center = 0x0B; else
+       if (freq <=  742500) if_band_center = 0x0C; else
+       if (freq <=  797500) if_band_center = 0x0D; else
+       if (freq <=  852500) if_band_center = 0x0E; else
+       if (freq <=  907500) if_band_center = 0x0F; else
+       if (freq <=  962500) if_band_center = 0x10; else
+       if (freq <= 1017500) if_band_center = 0x11; else
+       if (freq <= 1072500) if_band_center = 0x12; else if_band_center = 0x13;
+
+       b[0] = 1;
+       b[1] = (num1 >> 5) & 0xFF;
+       b[2] = (num1 & 0x1F);
+       b[3] = div1;
+       b[4] = (num2 >> 5) & 0xFF;
+       b[5] = num2 & 0x1F;
+       b[6] = div2;
+
+       dprintk(1, "IF1: %dMHz IF2: %dMHz\n", MT2131_IF1, MT2131_IF2);
+       dprintk(1, "PLL freq=%dkHz  band=%d\n", (int)freq, (int)if_band_center);
+       dprintk(1, "PLL f_lo1=%dkHz  f_lo2=%dkHz\n", (int)f_lo1, (int)f_lo2);
+       dprintk(1, "PLL div1=%d  num1=%d  div2=%d  num2=%d\n",
+               (int)div1, (int)num1, (int)div2, (int)num2);
+       dprintk(1, "PLL [1..6]: %2x %2x %2x %2x %2x %2x\n",
+               (int)b[1], (int)b[2], (int)b[3], (int)b[4], (int)b[5],
+               (int)b[6]);
+
+       ret = mt2131_writeregs(priv,b,7);
+       if (ret < 0)
+               return ret;
+
+       mt2131_writereg(priv, 0x0b, if_band_center);
+
+       /* Wait for lock */
+       i = 0;
+       do {
+               mt2131_readreg(priv, 0x08, &lockval);
+               if ((lockval & 0x88) == 0x88)
+                       break;
+               msleep(4);
+               i++;
+       } while (i < 10);
+
+       return ret;
+}
+
+static int mt2131_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct mt2131_priv *priv = fe->tuner_priv;
+       dprintk(1, "%s()\n", __func__);
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static int mt2131_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct mt2131_priv *priv = fe->tuner_priv;
+       dprintk(1, "%s()\n", __func__);
+       *bandwidth = priv->bandwidth;
+       return 0;
+}
+
+static int mt2131_get_status(struct dvb_frontend *fe, u32 *status)
+{
+       struct mt2131_priv *priv = fe->tuner_priv;
+       u8 lock_status = 0;
+       u8 afc_status = 0;
+
+       *status = 0;
+
+       mt2131_readreg(priv, 0x08, &lock_status);
+       if ((lock_status & 0x88) == 0x88)
+               *status = TUNER_STATUS_LOCKED;
+
+       mt2131_readreg(priv, 0x09, &afc_status);
+       dprintk(1, "%s() - LO Status = 0x%x, AFC Status = 0x%x\n",
+               __func__, lock_status, afc_status);
+
+       return 0;
+}
+
+static int mt2131_init(struct dvb_frontend *fe)
+{
+       struct mt2131_priv *priv = fe->tuner_priv;
+       int ret;
+       dprintk(1, "%s()\n", __func__);
+
+       if ((ret = mt2131_writeregs(priv, mt2131_config1,
+                                   sizeof(mt2131_config1))) < 0)
+               return ret;
+
+       mt2131_writereg(priv, 0x0b, 0x09);
+       mt2131_writereg(priv, 0x15, 0x47);
+       mt2131_writereg(priv, 0x07, 0xf2);
+       mt2131_writereg(priv, 0x0b, 0x01);
+
+       if ((ret = mt2131_writeregs(priv, mt2131_config2,
+                                   sizeof(mt2131_config2))) < 0)
+               return ret;
+
+       return ret;
+}
+
+static int mt2131_release(struct dvb_frontend *fe)
+{
+       dprintk(1, "%s()\n", __func__);
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static const struct dvb_tuner_ops mt2131_tuner_ops = {
+       .info = {
+               .name           = "Microtune MT2131",
+               .frequency_min  =  48000000,
+               .frequency_max  = 860000000,
+               .frequency_step =     50000,
+       },
+
+       .release       = mt2131_release,
+       .init          = mt2131_init,
+
+       .set_params    = mt2131_set_params,
+       .get_frequency = mt2131_get_frequency,
+       .get_bandwidth = mt2131_get_bandwidth,
+       .get_status    = mt2131_get_status
+};
+
+struct dvb_frontend * mt2131_attach(struct dvb_frontend *fe,
+                                   struct i2c_adapter *i2c,
+                                   struct mt2131_config *cfg, u16 if1)
+{
+       struct mt2131_priv *priv = NULL;
+       u8 id = 0;
+
+       dprintk(1, "%s()\n", __func__);
+
+       priv = kzalloc(sizeof(struct mt2131_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->cfg = cfg;
+       priv->bandwidth = 6000000; /* 6MHz */
+       priv->i2c = i2c;
+
+       if (mt2131_readreg(priv, 0, &id) != 0) {
+               kfree(priv);
+               return NULL;
+       }
+       if ( (id != 0x3E) && (id != 0x3F) ) {
+               printk(KERN_ERR "MT2131: Device not found at addr 0x%02x\n",
+                      cfg->i2c_address);
+               kfree(priv);
+               return NULL;
+       }
+
+       printk(KERN_INFO "MT2131: successfully identified at address 0x%02x\n",
+              cfg->i2c_address);
+       memcpy(&fe->ops.tuner_ops, &mt2131_tuner_ops,
+              sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = priv;
+       return fe;
+}
+EXPORT_SYMBOL(mt2131_attach);
+
+MODULE_AUTHOR("Steven Toth");
+MODULE_DESCRIPTION("Microtune MT2131 silicon tuner driver");
+MODULE_LICENSE("GPL");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
 
--- /dev/null
+/*
+ *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
+ *
+ *  Copyright (c) 2006 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 __MT2131_H__
+#define __MT2131_H__
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct mt2131_config {
+       u8 i2c_address;
+       u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
+};
+
+#if defined(CONFIG_DVB_TUNER_MT2131) || (defined(CONFIG_DVB_TUNER_MT2131_MODULE) && defined(MODULE))
+extern struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
+                                         struct i2c_adapter *i2c,
+                                         struct mt2131_config *cfg,
+                                         u16 if1);
+#else
+static inline struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
+                                                struct i2c_adapter *i2c,
+                                                struct mt2131_config *cfg,
+                                                u16 if1)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_TUNER_MT2131 */
+
+#endif /* __MT2131_H__ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
 
--- /dev/null
+/*
+ *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
+ *
+ *  Copyright (c) 2006 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 __MT2131_PRIV_H__
+#define __MT2131_PRIV_H__
+
+/* Regs */
+#define MT2131_PWR              0x07
+#define MT2131_UPC_1            0x0b
+#define MT2131_AGC_RL           0x10
+#define MT2131_MISC_2           0x15
+
+/* frequency values in KHz */
+#define MT2131_IF1              1220
+#define MT2131_IF2              44000
+#define MT2131_FREF             16000
+
+struct mt2131_priv {
+       struct mt2131_config *cfg;
+       struct i2c_adapter   *i2c;
+
+       u32 frequency;
+       u32 bandwidth;
+};
+
+#endif /* __MT2131_PRIV_H__ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
 
--- /dev/null
+/*
+ *  Driver for Microtune MT2266 "Direct conversion low power broadband tuner"
+ *
+ *  Copyright (c) 2007 Olivier DANET <odanet@caramail.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+#include "mt2266.h"
+
+#define I2C_ADDRESS 0x60
+
+#define REG_PART_REV   0
+#define REG_TUNE       1
+#define REG_BAND       6
+#define REG_BANDWIDTH  8
+#define REG_LOCK       0x12
+
+#define PART_REV 0x85
+
+struct mt2266_priv {
+       struct mt2266_config *cfg;
+       struct i2c_adapter   *i2c;
+
+       u32 frequency;
+       u32 bandwidth;
+       u8 band;
+};
+
+#define MT2266_VHF 1
+#define MT2266_UHF 0
+
+/* Here, frequencies are expressed in kiloHertz to avoid 32 bits overflows */
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+#define dprintk(args...) do { if (debug) {printk(KERN_DEBUG "MT2266: " args); printk("\n"); }} while (0)
+
+// Reads a single register
+static int mt2266_readreg(struct mt2266_priv *priv, u8 reg, u8 *val)
+{
+       struct i2c_msg msg[2] = {
+               { .addr = priv->cfg->i2c_address, .flags = 0,        .buf = ®, .len = 1 },
+               { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val,  .len = 1 },
+       };
+       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
+               printk(KERN_WARNING "MT2266 I2C read failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+// Writes a single register
+static int mt2266_writereg(struct mt2266_priv *priv, u8 reg, u8 val)
+{
+       u8 buf[2] = { reg, val };
+       struct i2c_msg msg = {
+               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2
+       };
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "MT2266 I2C write failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+// Writes a set of consecutive registers
+static int mt2266_writeregs(struct mt2266_priv *priv,u8 *buf, u8 len)
+{
+       struct i2c_msg msg = {
+               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = len
+       };
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "MT2266 I2C write failed (len=%i)\n",(int)len);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+// Initialisation sequences
+static u8 mt2266_init1[] = { REG_TUNE, 0x00, 0x00, 0x28,
+                                0x00, 0x52, 0x99, 0x3f };
+
+static u8 mt2266_init2[] = {
+    0x17, 0x6d, 0x71, 0x61, 0xc0, 0xbf, 0xff, 0xdc, 0x00, 0x0a, 0xd4,
+    0x03, 0x64, 0x64, 0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7f, 0x5e, 0x3f, 0xff, 0xff,
+    0xff, 0x00, 0x77, 0x0f, 0x2d
+};
+
+static u8 mt2266_init_8mhz[] = { REG_BANDWIDTH, 0x22, 0x22, 0x22, 0x22,
+                                               0x22, 0x22, 0x22, 0x22 };
+
+static u8 mt2266_init_7mhz[] = { REG_BANDWIDTH, 0x32, 0x32, 0x32, 0x32,
+                                               0x32, 0x32, 0x32, 0x32 };
+
+static u8 mt2266_init_6mhz[] = { REG_BANDWIDTH, 0xa7, 0xa7, 0xa7, 0xa7,
+                                               0xa7, 0xa7, 0xa7, 0xa7 };
+
+static u8 mt2266_uhf[] = { 0x1d, 0xdc, 0x00, 0x0a, 0xd4, 0x03, 0x64, 0x64,
+                          0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14 };
+
+static u8 mt2266_vhf[] = { 0x1d, 0xfe, 0x00, 0x00, 0xb4, 0x03, 0xa5, 0xa5,
+                          0xa5, 0xa5, 0x82, 0xaa, 0xf1, 0x17, 0x80, 0x1f };
+
+#define FREF 30000       // Quartz oscillator 30 MHz
+
+static int mt2266_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+       struct mt2266_priv *priv;
+       int ret=0;
+       u32 freq;
+       u32 tune;
+       u8  lnaband;
+       u8  b[10];
+       int i;
+       u8 band;
+
+       priv = fe->tuner_priv;
+
+       freq = params->frequency / 1000; // Hz -> kHz
+       if (freq < 470000 && freq > 230000)
+               return -EINVAL; /* Gap between VHF and UHF bands */
+       priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
+       priv->frequency = freq * 1000;
+
+       tune = 2 * freq * (8192/16) / (FREF/16);
+       band = (freq < 300000) ? MT2266_VHF : MT2266_UHF;
+       if (band == MT2266_VHF)
+               tune *= 2;
+
+       switch (params->u.ofdm.bandwidth) {
+       case BANDWIDTH_6_MHZ:
+               mt2266_writeregs(priv, mt2266_init_6mhz,
+                                sizeof(mt2266_init_6mhz));
+               break;
+       case BANDWIDTH_7_MHZ:
+               mt2266_writeregs(priv, mt2266_init_7mhz,
+                                sizeof(mt2266_init_7mhz));
+               break;
+       case BANDWIDTH_8_MHZ:
+       default:
+               mt2266_writeregs(priv, mt2266_init_8mhz,
+                                sizeof(mt2266_init_8mhz));
+               break;
+       }
+
+       if (band == MT2266_VHF && priv->band == MT2266_UHF) {
+               dprintk("Switch from UHF to VHF");
+               mt2266_writereg(priv, 0x05, 0x04);
+               mt2266_writereg(priv, 0x19, 0x61);
+               mt2266_writeregs(priv, mt2266_vhf, sizeof(mt2266_vhf));
+       } else if (band == MT2266_UHF && priv->band == MT2266_VHF) {
+               dprintk("Switch from VHF to UHF");
+               mt2266_writereg(priv, 0x05, 0x52);
+               mt2266_writereg(priv, 0x19, 0x61);
+               mt2266_writeregs(priv, mt2266_uhf, sizeof(mt2266_uhf));
+       }
+       msleep(10);
+
+       if (freq <= 495000)
+               lnaband = 0xEE;
+       else if (freq <= 525000)
+               lnaband = 0xDD;
+       else if (freq <= 550000)
+               lnaband = 0xCC;
+       else if (freq <= 580000)
+               lnaband = 0xBB;
+       else if (freq <= 605000)
+               lnaband = 0xAA;
+       else if (freq <= 630000)
+               lnaband = 0x99;
+       else if (freq <= 655000)
+               lnaband = 0x88;
+       else if (freq <= 685000)
+               lnaband = 0x77;
+       else if (freq <= 710000)
+               lnaband = 0x66;
+       else if (freq <= 735000)
+               lnaband = 0x55;
+       else if (freq <= 765000)
+               lnaband = 0x44;
+       else if (freq <= 802000)
+               lnaband = 0x33;
+       else if (freq <= 840000)
+               lnaband = 0x22;
+       else
+               lnaband = 0x11;
+
+       b[0] = REG_TUNE;
+       b[1] = (tune >> 8) & 0x1F;
+       b[2] = tune & 0xFF;
+       b[3] = tune >> 13;
+       mt2266_writeregs(priv,b,4);
+
+       dprintk("set_parms: tune=%d band=%d %s",
+               (int) tune, (int) lnaband,
+               (band == MT2266_UHF) ? "UHF" : "VHF");
+       dprintk("set_parms: [1..3]: %2x %2x %2x",
+               (int) b[1], (int) b[2], (int)b[3]);
+
+       if (band == MT2266_UHF) {
+               b[0] = 0x05;
+               b[1] = (priv->band == MT2266_VHF) ? 0x52 : 0x62;
+               b[2] = lnaband;
+               mt2266_writeregs(priv, b, 3);
+       }
+
+       /* Wait for pll lock or timeout */
+       i = 0;
+       do {
+               mt2266_readreg(priv,REG_LOCK,b);
+               if (b[0] & 0x40)
+                       break;
+               msleep(10);
+               i++;
+       } while (i<10);
+       dprintk("Lock when i=%i",(int)i);
+
+       if (band == MT2266_UHF && priv->band == MT2266_VHF)
+               mt2266_writereg(priv, 0x05, 0x62);
+
+       priv->band = band;
+
+       return ret;
+}
+
+static void mt2266_calibrate(struct mt2266_priv *priv)
+{
+       mt2266_writereg(priv, 0x11, 0x03);
+       mt2266_writereg(priv, 0x11, 0x01);
+       mt2266_writeregs(priv, mt2266_init1, sizeof(mt2266_init1));
+       mt2266_writeregs(priv, mt2266_init2, sizeof(mt2266_init2));
+       mt2266_writereg(priv, 0x33, 0x5e);
+       mt2266_writereg(priv, 0x10, 0x10);
+       mt2266_writereg(priv, 0x10, 0x00);
+       mt2266_writeregs(priv, mt2266_init_8mhz, sizeof(mt2266_init_8mhz));
+       msleep(25);
+       mt2266_writereg(priv, 0x17, 0x6d);
+       mt2266_writereg(priv, 0x1c, 0x00);
+       msleep(75);
+       mt2266_writereg(priv, 0x17, 0x6d);
+       mt2266_writereg(priv, 0x1c, 0xff);
+}
+
+static int mt2266_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct mt2266_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static int mt2266_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct mt2266_priv *priv = fe->tuner_priv;
+       *bandwidth = priv->bandwidth;
+       return 0;
+}
+
+static int mt2266_init(struct dvb_frontend *fe)
+{
+       int ret;
+       struct mt2266_priv *priv = fe->tuner_priv;
+       ret = mt2266_writereg(priv, 0x17, 0x6d);
+       if (ret < 0)
+               return ret;
+       ret = mt2266_writereg(priv, 0x1c, 0xff);
+       if (ret < 0)
+               return ret;
+       return 0;
+}
+
+static int mt2266_sleep(struct dvb_frontend *fe)
+{
+       struct mt2266_priv *priv = fe->tuner_priv;
+       mt2266_writereg(priv, 0x17, 0x6d);
+       mt2266_writereg(priv, 0x1c, 0x00);
+       return 0;
+}
+
+static int mt2266_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static const struct dvb_tuner_ops mt2266_tuner_ops = {
+       .info = {
+               .name           = "Microtune MT2266",
+               .frequency_min  = 174000000,
+               .frequency_max  = 862000000,
+               .frequency_step =     50000,
+       },
+       .release       = mt2266_release,
+       .init          = mt2266_init,
+       .sleep         = mt2266_sleep,
+       .set_params    = mt2266_set_params,
+       .get_frequency = mt2266_get_frequency,
+       .get_bandwidth = mt2266_get_bandwidth
+};
+
+struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg)
+{
+       struct mt2266_priv *priv = NULL;
+       u8 id = 0;
+
+       priv = kzalloc(sizeof(struct mt2266_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->cfg      = cfg;
+       priv->i2c      = i2c;
+       priv->band     = MT2266_UHF;
+
+       if (mt2266_readreg(priv, 0, &id)) {
+               kfree(priv);
+               return NULL;
+       }
+       if (id != PART_REV) {
+               kfree(priv);
+               return NULL;
+       }
+       printk(KERN_INFO "MT2266: successfully identified\n");
+       memcpy(&fe->ops.tuner_ops, &mt2266_tuner_ops, sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = priv;
+       mt2266_calibrate(priv);
+       return fe;
+}
+EXPORT_SYMBOL(mt2266_attach);
+
+MODULE_AUTHOR("Olivier DANET");
+MODULE_DESCRIPTION("Microtune MT2266 silicon tuner driver");
+MODULE_LICENSE("GPL");
 
--- /dev/null
+/*
+ *  Driver for Microtune MT2266 "Direct conversion low power broadband tuner"
+ *
+ *  Copyright (c) 2007 Olivier DANET <odanet@caramail.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+#ifndef MT2266_H
+#define MT2266_H
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct mt2266_config {
+       u8 i2c_address;
+};
+
+#if defined(CONFIG_DVB_TUNER_MT2266) || (defined(CONFIG_DVB_TUNER_MT2266_MODULE) && defined(MODULE))
+extern struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg);
+#else
+static inline struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_TUNER_MT2266
+
+#endif
 
--- /dev/null
+/*
+ *  Driver for Quantek QT1010 silicon tuner
+ *
+ *  Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
+ *                     Aapo Tahkola <aet@rasterburn.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include "qt1010.h"
+#include "qt1010_priv.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+#define dprintk(args...) \
+       do { \
+               if (debug) printk(KERN_DEBUG "QT1010: " args); \
+       } while (0)
+
+/* read single register */
+static int qt1010_readreg(struct qt1010_priv *priv, u8 reg, u8 *val)
+{
+       struct i2c_msg msg[2] = {
+               { .addr = priv->cfg->i2c_address,
+                 .flags = 0, .buf = ®, .len = 1 },
+               { .addr = priv->cfg->i2c_address,
+                 .flags = I2C_M_RD, .buf = val, .len = 1 },
+       };
+
+       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
+               printk(KERN_WARNING "qt1010 I2C read failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+/* write single register */
+static int qt1010_writereg(struct qt1010_priv *priv, u8 reg, u8 val)
+{
+       u8 buf[2] = { reg, val };
+       struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
+                              .flags = 0, .buf = buf, .len = 2 };
+
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "qt1010 I2C write failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+/* dump all registers */
+static void qt1010_dump_regs(struct qt1010_priv *priv)
+{
+       char buf[52], buf2[4];
+       u8 reg, val;
+
+       for (reg = 0; ; reg++) {
+               if (reg % 16 == 0) {
+                       if (reg)
+                               printk("%s\n", buf);
+                       sprintf(buf, "%02x: ", reg);
+               }
+               if (qt1010_readreg(priv, reg, &val) == 0)
+                       sprintf(buf2, "%02x ", val);
+               else
+                       strcpy(buf2, "-- ");
+               strcat(buf, buf2);
+               if (reg == 0x2f)
+                       break;
+       }
+       printk("%s\n", buf);
+}
+
+static int qt1010_set_params(struct dvb_frontend *fe,
+                            struct dvb_frontend_parameters *params)
+{
+       struct qt1010_priv *priv;
+       int err;
+       u32 freq, div, mod1, mod2;
+       u8 i, tmpval, reg05;
+       qt1010_i2c_oper_t rd[48] = {
+               { QT1010_WR, 0x01, 0x80 },
+               { QT1010_WR, 0x02, 0x3f },
+               { QT1010_WR, 0x05, 0xff }, /* 02 c write */
+               { QT1010_WR, 0x06, 0x44 },
+               { QT1010_WR, 0x07, 0xff }, /* 04 c write */
+               { QT1010_WR, 0x08, 0x08 },
+               { QT1010_WR, 0x09, 0xff }, /* 06 c write */
+               { QT1010_WR, 0x0a, 0xff }, /* 07 c write */
+               { QT1010_WR, 0x0b, 0xff }, /* 08 c write */
+               { QT1010_WR, 0x0c, 0xe1 },
+               { QT1010_WR, 0x1a, 0xff }, /* 10 c write */
+               { QT1010_WR, 0x1b, 0x00 },
+               { QT1010_WR, 0x1c, 0x89 },
+               { QT1010_WR, 0x11, 0xff }, /* 13 c write */
+               { QT1010_WR, 0x12, 0xff }, /* 14 c write */
+               { QT1010_WR, 0x22, 0xff }, /* 15 c write */
+               { QT1010_WR, 0x1e, 0x00 },
+               { QT1010_WR, 0x1e, 0xd0 },
+               { QT1010_RD, 0x22, 0xff }, /* 16 c read */
+               { QT1010_WR, 0x1e, 0x00 },
+               { QT1010_RD, 0x05, 0xff }, /* 20 c read */
+               { QT1010_RD, 0x22, 0xff }, /* 21 c read */
+               { QT1010_WR, 0x23, 0xd0 },
+               { QT1010_WR, 0x1e, 0x00 },
+               { QT1010_WR, 0x1e, 0xe0 },
+               { QT1010_RD, 0x23, 0xff }, /* 25 c read */
+               { QT1010_RD, 0x23, 0xff }, /* 26 c read */
+               { QT1010_WR, 0x1e, 0x00 },
+               { QT1010_WR, 0x24, 0xd0 },
+               { QT1010_WR, 0x1e, 0x00 },
+               { QT1010_WR, 0x1e, 0xf0 },
+               { QT1010_RD, 0x24, 0xff }, /* 31 c read */
+               { QT1010_WR, 0x1e, 0x00 },
+               { QT1010_WR, 0x14, 0x7f },
+               { QT1010_WR, 0x15, 0x7f },
+               { QT1010_WR, 0x05, 0xff }, /* 35 c write */
+               { QT1010_WR, 0x06, 0x00 },
+               { QT1010_WR, 0x15, 0x1f },
+               { QT1010_WR, 0x16, 0xff },
+               { QT1010_WR, 0x18, 0xff },
+               { QT1010_WR, 0x1f, 0xff }, /* 40 c write */
+               { QT1010_WR, 0x20, 0xff }, /* 41 c write */
+               { QT1010_WR, 0x21, 0x53 },
+               { QT1010_WR, 0x25, 0xff }, /* 43 c write */
+               { QT1010_WR, 0x26, 0x15 },
+               { QT1010_WR, 0x00, 0xff }, /* 45 c write */
+               { QT1010_WR, 0x02, 0x00 },
+               { QT1010_WR, 0x01, 0x00 }
+       };
+
+#define FREQ1 32000000 /* 32 MHz */
+#define FREQ2  4000000 /* 4 MHz Quartz oscillator in the stick? */
+
+       priv = fe->tuner_priv;
+       freq = params->frequency;
+       div = (freq + QT1010_OFFSET) / QT1010_STEP;
+       freq = (div * QT1010_STEP) - QT1010_OFFSET;
+       mod1 = (freq + QT1010_OFFSET) % FREQ1;
+       mod2 = (freq + QT1010_OFFSET) % FREQ2;
+       priv->bandwidth =
+               (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
+       priv->frequency = freq;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+       /* reg 05 base value */
+       if      (freq < 290000000) reg05 = 0x14; /* 290 MHz */
+       else if (freq < 610000000) reg05 = 0x34; /* 610 MHz */
+       else if (freq < 802000000) reg05 = 0x54; /* 802 MHz */
+       else                       reg05 = 0x74;
+
+       /* 0x5 */
+       rd[2].val = reg05;
+
+       /* 07 - set frequency: 32 MHz scale */
+       rd[4].val = (freq + QT1010_OFFSET) / FREQ1;
+
+       /* 09 - changes every 8/24 MHz */
+       if (mod1 < 8000000) rd[6].val = 0x1d;
+       else                rd[6].val = 0x1c;
+
+       /* 0a - set frequency: 4 MHz scale (max 28 MHz) */
+       if      (mod1 < 1*FREQ2) rd[7].val = 0x09; /*  +0 MHz */
+       else if (mod1 < 2*FREQ2) rd[7].val = 0x08; /*  +4 MHz */
+       else if (mod1 < 3*FREQ2) rd[7].val = 0x0f; /*  +8 MHz */
+       else if (mod1 < 4*FREQ2) rd[7].val = 0x0e; /* +12 MHz */
+       else if (mod1 < 5*FREQ2) rd[7].val = 0x0d; /* +16 MHz */
+       else if (mod1 < 6*FREQ2) rd[7].val = 0x0c; /* +20 MHz */
+       else if (mod1 < 7*FREQ2) rd[7].val = 0x0b; /* +24 MHz */
+       else                     rd[7].val = 0x0a; /* +28 MHz */
+
+       /* 0b - changes every 2/2 MHz */
+       if (mod2 < 2000000) rd[8].val = 0x45;
+       else                rd[8].val = 0x44;
+
+       /* 1a - set frequency: 125 kHz scale (max 3875 kHz)*/
+       tmpval = 0x78; /* byte, overflows intentionally */
+       rd[10].val = tmpval-((mod2/QT1010_STEP)*0x08);
+
+       /* 11 */
+       rd[13].val = 0xfd; /* TODO: correct value calculation */
+
+       /* 12 */
+       rd[14].val = 0x91; /* TODO: correct value calculation */
+
+       /* 22 */
+       if      (freq < 450000000) rd[15].val = 0xd0; /* 450 MHz */
+       else if (freq < 482000000) rd[15].val = 0xd1; /* 482 MHz */
+       else if (freq < 514000000) rd[15].val = 0xd4; /* 514 MHz */
+       else if (freq < 546000000) rd[15].val = 0xd7; /* 546 MHz */
+       else if (freq < 610000000) rd[15].val = 0xda; /* 610 MHz */
+       else                       rd[15].val = 0xd0;
+
+       /* 05 */
+       rd[35].val = (reg05 & 0xf0);
+
+       /* 1f */
+       if      (mod1 <  8000000) tmpval = 0x00;
+       else if (mod1 < 12000000) tmpval = 0x01;
+       else if (mod1 < 16000000) tmpval = 0x02;
+       else if (mod1 < 24000000) tmpval = 0x03;
+       else if (mod1 < 28000000) tmpval = 0x04;
+       else                      tmpval = 0x05;
+       rd[40].val = (priv->reg1f_init_val + 0x0e + tmpval);
+
+       /* 20 */
+       if      (mod1 <  8000000) tmpval = 0x00;
+       else if (mod1 < 12000000) tmpval = 0x01;
+       else if (mod1 < 20000000) tmpval = 0x02;
+       else if (mod1 < 24000000) tmpval = 0x03;
+       else if (mod1 < 28000000) tmpval = 0x04;
+       else                      tmpval = 0x05;
+       rd[41].val = (priv->reg20_init_val + 0x0d + tmpval);
+
+       /* 25 */
+       rd[43].val = priv->reg25_init_val;
+
+       /* 00 */
+       rd[45].val = 0x92; /* TODO: correct value calculation */
+
+       dprintk("freq:%u 05:%02x 07:%02x 09:%02x 0a:%02x 0b:%02x " \
+               "1a:%02x 11:%02x 12:%02x 22:%02x 05:%02x 1f:%02x " \
+               "20:%02x 25:%02x 00:%02x", \
+               freq, rd[2].val, rd[4].val, rd[6].val, rd[7].val, rd[8].val, \
+               rd[10].val, rd[13].val, rd[14].val, rd[15].val, rd[35].val, \
+               rd[40].val, rd[41].val, rd[43].val, rd[45].val);
+
+       for (i = 0; i < ARRAY_SIZE(rd); i++) {
+               if (rd[i].oper == QT1010_WR) {
+                       err = qt1010_writereg(priv, rd[i].reg, rd[i].val);
+               } else { /* read is required to proper locking */
+                       err = qt1010_readreg(priv, rd[i].reg, &tmpval);
+               }
+               if (err) return err;
+       }
+
+       if (debug)
+               qt1010_dump_regs(priv);
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+       return 0;
+}
+
+static int qt1010_init_meas1(struct qt1010_priv *priv,
+                            u8 oper, u8 reg, u8 reg_init_val, u8 *retval)
+{
+       u8 i, val1, val2;
+       int err;
+
+       qt1010_i2c_oper_t i2c_data[] = {
+               { QT1010_WR, reg, reg_init_val },
+               { QT1010_WR, 0x1e, 0x00 },
+               { QT1010_WR, 0x1e, oper },
+               { QT1010_RD, reg, 0xff }
+       };
+
+       for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
+               if (i2c_data[i].oper == QT1010_WR) {
+                       err = qt1010_writereg(priv, i2c_data[i].reg,
+                                             i2c_data[i].val);
+               } else {
+                       err = qt1010_readreg(priv, i2c_data[i].reg, &val2);
+               }
+               if (err) return err;
+       }
+
+       do {
+               val1 = val2;
+               err = qt1010_readreg(priv, reg, &val2);
+               if (err) return err;
+               dprintk("compare reg:%02x %02x %02x", reg, val1, val2);
+       } while (val1 != val2);
+       *retval = val1;
+
+       return qt1010_writereg(priv, 0x1e, 0x00);
+}
+
+static u8 qt1010_init_meas2(struct qt1010_priv *priv,
+                           u8 reg_init_val, u8 *retval)
+{
+       u8 i, val;
+       int err;
+       qt1010_i2c_oper_t i2c_data[] = {
+               { QT1010_WR, 0x07, reg_init_val },
+               { QT1010_WR, 0x22, 0xd0 },
+               { QT1010_WR, 0x1e, 0x00 },
+               { QT1010_WR, 0x1e, 0xd0 },
+               { QT1010_RD, 0x22, 0xff },
+               { QT1010_WR, 0x1e, 0x00 },
+               { QT1010_WR, 0x22, 0xff }
+       };
+       for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
+               if (i2c_data[i].oper == QT1010_WR) {
+                       err = qt1010_writereg(priv, i2c_data[i].reg,
+                                             i2c_data[i].val);
+               } else {
+                       err = qt1010_readreg(priv, i2c_data[i].reg, &val);
+               }
+               if (err) return err;
+       }
+       *retval = val;
+       return 0;
+}
+
+static int qt1010_init(struct dvb_frontend *fe)
+{
+       struct qt1010_priv *priv = fe->tuner_priv;
+       struct dvb_frontend_parameters params;
+       int err = 0;
+       u8 i, tmpval, *valptr = NULL;
+
+       qt1010_i2c_oper_t i2c_data[] = {
+               { QT1010_WR, 0x01, 0x80 },
+               { QT1010_WR, 0x0d, 0x84 },
+               { QT1010_WR, 0x0e, 0xb7 },
+               { QT1010_WR, 0x2a, 0x23 },
+               { QT1010_WR, 0x2c, 0xdc },
+               { QT1010_M1, 0x25, 0x40 }, /* get reg 25 init value */
+               { QT1010_M1, 0x81, 0xff }, /* get reg 25 init value */
+               { QT1010_WR, 0x2b, 0x70 },
+               { QT1010_WR, 0x2a, 0x23 },
+               { QT1010_M1, 0x26, 0x08 },
+               { QT1010_M1, 0x82, 0xff },
+               { QT1010_WR, 0x05, 0x14 },
+               { QT1010_WR, 0x06, 0x44 },
+               { QT1010_WR, 0x07, 0x28 },
+               { QT1010_WR, 0x08, 0x0b },
+               { QT1010_WR, 0x11, 0xfd },
+               { QT1010_M1, 0x22, 0x0d },
+               { QT1010_M1, 0xd0, 0xff },
+               { QT1010_WR, 0x06, 0x40 },
+               { QT1010_WR, 0x16, 0xf0 },
+               { QT1010_WR, 0x02, 0x38 },
+               { QT1010_WR, 0x03, 0x18 },
+               { QT1010_WR, 0x20, 0xe0 },
+               { QT1010_M1, 0x1f, 0x20 }, /* get reg 1f init value */
+               { QT1010_M1, 0x84, 0xff }, /* get reg 1f init value */
+               { QT1010_RD, 0x20, 0x20 }, /* get reg 20 init value */
+               { QT1010_WR, 0x03, 0x19 },
+               { QT1010_WR, 0x02, 0x3f },
+               { QT1010_WR, 0x21, 0x53 },
+               { QT1010_RD, 0x21, 0xff },
+               { QT1010_WR, 0x11, 0xfd },
+               { QT1010_WR, 0x05, 0x34 },
+               { QT1010_WR, 0x06, 0x44 },
+               { QT1010_WR, 0x08, 0x08 }
+       };
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+       for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
+               switch (i2c_data[i].oper) {
+               case QT1010_WR:
+                       err = qt1010_writereg(priv, i2c_data[i].reg,
+                                             i2c_data[i].val);
+                       break;
+               case QT1010_RD:
+                       if (i2c_data[i].val == 0x20)
+                               valptr = &priv->reg20_init_val;
+                       else
+                               valptr = &tmpval;
+                       err = qt1010_readreg(priv, i2c_data[i].reg, valptr);
+                       break;
+               case QT1010_M1:
+                       if (i2c_data[i].val == 0x25)
+                               valptr = &priv->reg25_init_val;
+                       else if (i2c_data[i].val == 0x1f)
+                               valptr = &priv->reg1f_init_val;
+                       else
+                               valptr = &tmpval;
+                       err = qt1010_init_meas1(priv, i2c_data[i+1].reg,
+                                               i2c_data[i].reg,
+                                               i2c_data[i].val, valptr);
+                       i++;
+                       break;
+               }
+               if (err) return err;
+       }
+
+       for (i = 0x31; i < 0x3a; i++) /* 0x31 - 0x39 */
+               if ((err = qt1010_init_meas2(priv, i, &tmpval)))
+                       return err;
+
+       params.frequency = 545000000; /* Sigmatek DVB-110 545000000 */
+                                     /* MSI Megasky 580 GL861 533000000 */
+       return qt1010_set_params(fe, ¶ms);
+}
+
+static int qt1010_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static int qt1010_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct qt1010_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static int qt1010_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct qt1010_priv *priv = fe->tuner_priv;
+       *bandwidth = priv->bandwidth;
+       return 0;
+}
+
+static const struct dvb_tuner_ops qt1010_tuner_ops = {
+       .info = {
+               .name           = "Quantek QT1010",
+               .frequency_min  = QT1010_MIN_FREQ,
+               .frequency_max  = QT1010_MAX_FREQ,
+               .frequency_step = QT1010_STEP,
+       },
+
+       .release       = qt1010_release,
+       .init          = qt1010_init,
+       /* TODO: implement sleep */
+
+       .set_params    = qt1010_set_params,
+       .get_frequency = qt1010_get_frequency,
+       .get_bandwidth = qt1010_get_bandwidth
+};
+
+struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe,
+                                   struct i2c_adapter *i2c,
+                                   struct qt1010_config *cfg)
+{
+       struct qt1010_priv *priv = NULL;
+       u8 id;
+
+       priv = kzalloc(sizeof(struct qt1010_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->cfg = cfg;
+       priv->i2c = i2c;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+
+       /* Try to detect tuner chip. Probably this is not correct register. */
+       if (qt1010_readreg(priv, 0x29, &id) != 0 || (id != 0x39)) {
+               kfree(priv);
+               return NULL;
+       }
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+       printk(KERN_INFO "Quantek QT1010 successfully identified.\n");
+       memcpy(&fe->ops.tuner_ops, &qt1010_tuner_ops,
+              sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = priv;
+       return fe;
+}
+EXPORT_SYMBOL(qt1010_attach);
+
+MODULE_DESCRIPTION("Quantek QT1010 silicon tuner driver");
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>");
+MODULE_VERSION("0.1");
+MODULE_LICENSE("GPL");
 
--- /dev/null
+/*
+ *  Driver for Quantek QT1010 silicon tuner
+ *
+ *  Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
+ *                     Aapo Tahkola <aet@rasterburn.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef QT1010_H
+#define QT1010_H
+
+#include "dvb_frontend.h"
+
+struct qt1010_config {
+       u8 i2c_address;
+};
+
+/**
+ * Attach a qt1010 tuner to the supplied frontend structure.
+ *
+ * @param fe   frontend to attach to
+ * @param i2c  i2c adapter to use
+ * @param cfg  tuner hw based configuration
+ * @return fe  pointer on success, NULL on failure
+ */
+#if defined(CONFIG_DVB_TUNER_QT1010) || (defined(CONFIG_DVB_TUNER_QT1010_MODULE) && defined(MODULE))
+extern struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe,
+                                         struct i2c_adapter *i2c,
+                                         struct qt1010_config *cfg);
+#else
+static inline struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe,
+                                                struct i2c_adapter *i2c,
+                                                struct qt1010_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif // CONFIG_DVB_TUNER_QT1010
+
+#endif
 
--- /dev/null
+/*
+ *  Driver for Quantek QT1010 silicon tuner
+ *
+ *  Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
+ *                     Aapo Tahkola <aet@rasterburn.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef QT1010_PRIV_H
+#define QT1010_PRIV_H
+
+/*
+reg def meaning
+=== === =======
+00  00  ?
+01  a0  ? operation start/stop; start=80, stop=00
+02  00  ?
+03  19  ?
+04  00  ?
+05  00  ? maybe band selection
+06  00  ?
+07  2b  set frequency: 32 MHz scale, n*32 MHz
+08  0b  ?
+09  10  ? changes every 8/24 MHz; values 1d/1c
+0a  08  set frequency: 4 MHz scale, n*4 MHz
+0b  41  ? changes every 2/2 MHz; values 45/45
+0c  e1  ?
+0d  94  ?
+0e  b6  ?
+0f  2c  ?
+10  10  ?
+11  f1  ? maybe device specified adjustment
+12  11  ? maybe device specified adjustment
+13  3f  ?
+14  1f  ?
+15  3f  ?
+16  ff  ?
+17  ff  ?
+18  f7  ?
+19  80  ?
+1a  d0  set frequency: 125 kHz scale, n*125 kHz
+1b  00  ?
+1c  89  ?
+1d  00  ?
+1e  00  ? looks like operation register; write cmd here, read result from 1f-26
+1f  20  ? chip initialization
+20  e0  ? chip initialization
+21  20  ?
+22  d0  ?
+23  d0  ?
+24  d0  ?
+25  40  ? chip initialization
+26  08  ?
+27  29  ?
+28  55  ?
+29  39  ?
+2a  13  ?
+2b  01  ?
+2c  ea  ?
+2d  00  ?
+2e  00  ? not used?
+2f  00  ? not used?
+*/
+
+#define QT1010_STEP         125000 /*  125 kHz used by Windows drivers,
+                                     hw could be more precise but we don't
+                                     know how to use */
+#define QT1010_MIN_FREQ   48000000 /*   48 MHz */
+#define QT1010_MAX_FREQ  860000000 /*  860 MHz */
+#define QT1010_OFFSET   1246000000 /* 1246 MHz */
+
+#define QT1010_WR 0
+#define QT1010_RD 1
+#define QT1010_M1 3
+
+typedef struct {
+       u8 oper, reg, val;
+} qt1010_i2c_oper_t;
+
+struct qt1010_priv {
+       struct qt1010_config *cfg;
+       struct i2c_adapter   *i2c;
+
+       u8 reg1f_init_val;
+       u8 reg20_init_val;
+       u8 reg25_init_val;
+
+       u32 frequency;
+       u32 bandwidth;
+};
+
+#endif
 
          An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
          to support this frontend.
 
-comment "Tuners/PLL support"
+comment "Digital terrestrial only tuners/PLL"
        depends on DVB_CORE
 
 config DVB_PLL
          This module drives a number of tuners based on PLL chips with a
          common I2C interface. Say Y when you want to support these tuners.
 
-config DVB_TUNER_QT1010
-       tristate "Quantek QT1010 silicon tuner"
-       depends on DVB_CORE && I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A driver for the silicon tuner QT1010 from Quantek.
-
-config DVB_TUNER_MT2060
-       tristate "Microtune MT2060 silicon IF tuner"
-       depends on I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A driver for the silicon IF tuner MT2060 from Microtune.
-
-config DVB_TUNER_MT2266
-       tristate "Microtune MT2266 silicon tuner"
-       depends on I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A driver for the silicon baseband tuner MT2266 from Microtune.
-
-config DVB_TUNER_MT2131
-       tristate "Microtune MT2131 silicon tuner"
-       depends on I2C
-       default m if DVB_FE_CUSTOMISE
-       help
-         A driver for the silicon baseband tuner MT2131 from Microtune.
-
 config DVB_TUNER_DIB0070
        tristate "DiBcom DiB0070 silicon base-band tuner"
        depends on I2C
 
 obj-$(CONFIG_DVB_ISL6421) += isl6421.o
 obj-$(CONFIG_DVB_TDA10086) += tda10086.o
 obj-$(CONFIG_DVB_TDA826X) += tda826x.o
-obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o
-obj-$(CONFIG_DVB_TUNER_MT2266) += mt2266.o
 obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o
-obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o
 obj-$(CONFIG_DVB_TUA6100) += tua6100.o
-obj-$(CONFIG_DVB_TUNER_MT2131) += mt2131.o
 obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
 obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o
 obj-$(CONFIG_DVB_AU8522) += au8522.o
 
+++ /dev/null
-/*
- *  Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
- *
- *  Copyright (c) 2006 Olivier DANET <odanet@caramail.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
- */
-
-/* In that file, frequencies are expressed in kiloHertz to avoid 32 bits overflows */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/dvb/frontend.h>
-#include <linux/i2c.h>
-
-#include "dvb_frontend.h"
-
-#include "mt2060.h"
-#include "mt2060_priv.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-#define dprintk(args...) do { if (debug) {printk(KERN_DEBUG "MT2060: " args); printk("\n"); }} while (0)
-
-// Reads a single register
-static int mt2060_readreg(struct mt2060_priv *priv, u8 reg, u8 *val)
-{
-       struct i2c_msg msg[2] = {
-               { .addr = priv->cfg->i2c_address, .flags = 0,        .buf = ®, .len = 1 },
-               { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val,  .len = 1 },
-       };
-
-       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
-               printk(KERN_WARNING "mt2060 I2C read failed\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-// Writes a single register
-static int mt2060_writereg(struct mt2060_priv *priv, u8 reg, u8 val)
-{
-       u8 buf[2] = { reg, val };
-       struct i2c_msg msg = {
-               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2
-       };
-
-       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
-               printk(KERN_WARNING "mt2060 I2C write failed\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-// Writes a set of consecutive registers
-static int mt2060_writeregs(struct mt2060_priv *priv,u8 *buf, u8 len)
-{
-       struct i2c_msg msg = {
-               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = len
-       };
-       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
-               printk(KERN_WARNING "mt2060 I2C write failed (len=%i)\n",(int)len);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-// Initialisation sequences
-// LNABAND=3, NUM1=0x3C, DIV1=0x74, NUM2=0x1080, DIV2=0x49
-static u8 mt2060_config1[] = {
-       REG_LO1C1,
-       0x3F,   0x74,   0x00,   0x08,   0x93
-};
-
-// FMCG=2, GP2=0, GP1=0
-static u8 mt2060_config2[] = {
-       REG_MISC_CTRL,
-       0x20,   0x1E,   0x30,   0xff,   0x80,   0xff,   0x00,   0x2c,   0x42
-};
-
-//  VGAG=3, V1CSE=1
-
-#ifdef  MT2060_SPURCHECK
-/* The function below calculates the frequency offset between the output frequency if2
- and the closer cross modulation subcarrier between lo1 and lo2 up to the tenth harmonic */
-static int mt2060_spurcalc(u32 lo1,u32 lo2,u32 if2)
-{
-       int I,J;
-       int dia,diamin,diff;
-       diamin=1000000;
-       for (I = 1; I < 10; I++) {
-               J = ((2*I*lo1)/lo2+1)/2;
-               diff = I*(int)lo1-J*(int)lo2;
-               if (diff < 0) diff=-diff;
-               dia = (diff-(int)if2);
-               if (dia < 0) dia=-dia;
-               if (diamin > dia) diamin=dia;
-       }
-       return diamin;
-}
-
-#define BANDWIDTH 4000 // kHz
-
-/* Calculates the frequency offset to add to avoid spurs. Returns 0 if no offset is needed */
-static int mt2060_spurcheck(u32 lo1,u32 lo2,u32 if2)
-{
-       u32 Spur,Sp1,Sp2;
-       int I,J;
-       I=0;
-       J=1000;
-
-       Spur=mt2060_spurcalc(lo1,lo2,if2);
-       if (Spur < BANDWIDTH) {
-               /* Potential spurs detected */
-               dprintk("Spurs before : f_lo1: %d  f_lo2: %d  (kHz)",
-                       (int)lo1,(int)lo2);
-               I=1000;
-               Sp1 = mt2060_spurcalc(lo1+I,lo2+I,if2);
-               Sp2 = mt2060_spurcalc(lo1-I,lo2-I,if2);
-
-               if (Sp1 < Sp2) {
-                       J=-J; I=-I; Spur=Sp2;
-               } else
-                       Spur=Sp1;
-
-               while (Spur < BANDWIDTH) {
-                       I += J;
-                       Spur = mt2060_spurcalc(lo1+I,lo2+I,if2);
-               }
-               dprintk("Spurs after  : f_lo1: %d  f_lo2: %d  (kHz)",
-                       (int)(lo1+I),(int)(lo2+I));
-       }
-       return I;
-}
-#endif
-
-#define IF2  36150       // IF2 frequency = 36.150 MHz
-#define FREF 16000       // Quartz oscillator 16 MHz
-
-static int mt2060_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
-{
-       struct mt2060_priv *priv;
-       int ret=0;
-       int i=0;
-       u32 freq;
-       u8  lnaband;
-       u32 f_lo1,f_lo2;
-       u32 div1,num1,div2,num2;
-       u8  b[8];
-       u32 if1;
-
-       priv = fe->tuner_priv;
-
-       if1 = priv->if1_freq;
-       b[0] = REG_LO1B1;
-       b[1] = 0xFF;
-
-       mt2060_writeregs(priv,b,2);
-
-       freq = params->frequency / 1000; // Hz -> kHz
-       priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
-
-       f_lo1 = freq + if1 * 1000;
-       f_lo1 = (f_lo1 / 250) * 250;
-       f_lo2 = f_lo1 - freq - IF2;
-       // From the Comtech datasheet, the step used is 50kHz. The tuner chip could be more precise
-       f_lo2 = ((f_lo2 + 25) / 50) * 50;
-       priv->frequency =  (f_lo1 - f_lo2 - IF2) * 1000,
-
-#ifdef MT2060_SPURCHECK
-       // LO-related spurs detection and correction
-       num1   = mt2060_spurcheck(f_lo1,f_lo2,IF2);
-       f_lo1 += num1;
-       f_lo2 += num1;
-#endif
-       //Frequency LO1 = 16MHz * (DIV1 + NUM1/64 )
-       num1 = f_lo1 / (FREF / 64);
-       div1 = num1 / 64;
-       num1 &= 0x3f;
-
-       // Frequency LO2 = 16MHz * (DIV2 + NUM2/8192 )
-       num2 = f_lo2 * 64 / (FREF / 128);
-       div2 = num2 / 8192;
-       num2 &= 0x1fff;
-
-       if (freq <=  95000) lnaband = 0xB0; else
-       if (freq <= 180000) lnaband = 0xA0; else
-       if (freq <= 260000) lnaband = 0x90; else
-       if (freq <= 335000) lnaband = 0x80; else
-       if (freq <= 425000) lnaband = 0x70; else
-       if (freq <= 480000) lnaband = 0x60; else
-       if (freq <= 570000) lnaband = 0x50; else
-       if (freq <= 645000) lnaband = 0x40; else
-       if (freq <= 730000) lnaband = 0x30; else
-       if (freq <= 810000) lnaband = 0x20; else lnaband = 0x10;
-
-       b[0] = REG_LO1C1;
-       b[1] = lnaband | ((num1 >>2) & 0x0F);
-       b[2] = div1;
-       b[3] = (num2 & 0x0F)  | ((num1 & 3) << 4);
-       b[4] = num2 >> 4;
-       b[5] = ((num2 >>12) & 1) | (div2 << 1);
-
-       dprintk("IF1: %dMHz",(int)if1);
-       dprintk("PLL freq=%dkHz  f_lo1=%dkHz  f_lo2=%dkHz",(int)freq,(int)f_lo1,(int)f_lo2);
-       dprintk("PLL div1=%d  num1=%d  div2=%d  num2=%d",(int)div1,(int)num1,(int)div2,(int)num2);
-       dprintk("PLL [1..5]: %2x %2x %2x %2x %2x",(int)b[1],(int)b[2],(int)b[3],(int)b[4],(int)b[5]);
-
-       mt2060_writeregs(priv,b,6);
-
-       //Waits for pll lock or timeout
-       i = 0;
-       do {
-               mt2060_readreg(priv,REG_LO_STATUS,b);
-               if ((b[0] & 0x88)==0x88)
-                       break;
-               msleep(4);
-               i++;
-       } while (i<10);
-
-       return ret;
-}
-
-static void mt2060_calibrate(struct mt2060_priv *priv)
-{
-       u8 b = 0;
-       int i = 0;
-
-       if (mt2060_writeregs(priv,mt2060_config1,sizeof(mt2060_config1)))
-               return;
-       if (mt2060_writeregs(priv,mt2060_config2,sizeof(mt2060_config2)))
-               return;
-
-       /* initialize the clock output */
-       mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x30);
-
-       do {
-               b |= (1 << 6); // FM1SS;
-               mt2060_writereg(priv, REG_LO2C1,b);
-               msleep(20);
-
-               if (i == 0) {
-                       b |= (1 << 7); // FM1CA;
-                       mt2060_writereg(priv, REG_LO2C1,b);
-                       b &= ~(1 << 7); // FM1CA;
-                       msleep(20);
-               }
-
-               b &= ~(1 << 6); // FM1SS
-               mt2060_writereg(priv, REG_LO2C1,b);
-
-               msleep(20);
-               i++;
-       } while (i < 9);
-
-       i = 0;
-       while (i++ < 10 && mt2060_readreg(priv, REG_MISC_STAT, &b) == 0 && (b & (1 << 6)) == 0)
-               msleep(20);
-
-       if (i < 10) {
-               mt2060_readreg(priv, REG_FM_FREQ, &priv->fmfreq); // now find out, what is fmreq used for :)
-               dprintk("calibration was successful: %d", (int)priv->fmfreq);
-       } else
-               dprintk("FMCAL timed out");
-}
-
-static int mt2060_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct mt2060_priv *priv = fe->tuner_priv;
-       *frequency = priv->frequency;
-       return 0;
-}
-
-static int mt2060_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct mt2060_priv *priv = fe->tuner_priv;
-       *bandwidth = priv->bandwidth;
-       return 0;
-}
-
-static int mt2060_init(struct dvb_frontend *fe)
-{
-       struct mt2060_priv *priv = fe->tuner_priv;
-       return mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x33);
-}
-
-static int mt2060_sleep(struct dvb_frontend *fe)
-{
-       struct mt2060_priv *priv = fe->tuner_priv;
-       return mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x30);
-}
-
-static int mt2060_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static const struct dvb_tuner_ops mt2060_tuner_ops = {
-       .info = {
-               .name           = "Microtune MT2060",
-               .frequency_min  =  48000000,
-               .frequency_max  = 860000000,
-               .frequency_step =     50000,
-       },
-
-       .release       = mt2060_release,
-
-       .init          = mt2060_init,
-       .sleep         = mt2060_sleep,
-
-       .set_params    = mt2060_set_params,
-       .get_frequency = mt2060_get_frequency,
-       .get_bandwidth = mt2060_get_bandwidth
-};
-
-/* This functions tries to identify a MT2060 tuner by reading the PART/REV register. This is hasty. */
-struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
-{
-       struct mt2060_priv *priv = NULL;
-       u8 id = 0;
-
-       priv = kzalloc(sizeof(struct mt2060_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->cfg      = cfg;
-       priv->i2c      = i2c;
-       priv->if1_freq = if1;
-
-       if (mt2060_readreg(priv,REG_PART_REV,&id) != 0) {
-               kfree(priv);
-               return NULL;
-       }
-
-       if (id != PART_REV) {
-               kfree(priv);
-               return NULL;
-       }
-       printk(KERN_INFO "MT2060: successfully identified (IF1 = %d)\n", if1);
-       memcpy(&fe->ops.tuner_ops, &mt2060_tuner_ops, sizeof(struct dvb_tuner_ops));
-
-       fe->tuner_priv = priv;
-
-       mt2060_calibrate(priv);
-
-       return fe;
-}
-EXPORT_SYMBOL(mt2060_attach);
-
-MODULE_AUTHOR("Olivier DANET");
-MODULE_DESCRIPTION("Microtune MT2060 silicon tuner driver");
-MODULE_LICENSE("GPL");
 
+++ /dev/null
-/*
- *  Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
- *
- *  Copyright (c) 2006 Olivier DANET <odanet@caramail.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
- */
-
-#ifndef MT2060_H
-#define MT2060_H
-
-struct dvb_frontend;
-struct i2c_adapter;
-
-struct mt2060_config {
-       u8 i2c_address;
-       u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
-};
-
-#if defined(CONFIG_DVB_TUNER_MT2060) || (defined(CONFIG_DVB_TUNER_MT2060_MODULE) && defined(MODULE))
-extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1);
-#else
-static inline struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_TUNER_MT2060
-
-#endif
 
+++ /dev/null
-/*
- *  Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
- *
- *  Copyright (c) 2006 Olivier DANET <odanet@caramail.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
- */
-
-#ifndef MT2060_PRIV_H
-#define MT2060_PRIV_H
-
-// Uncomment the #define below to enable spurs checking. The results where quite unconvincing.
-// #define MT2060_SPURCHECK
-
-/* This driver is based on the information available in the datasheet of the
-   "Comtech SDVBT-3K6M" tuner ( K1000737843.pdf ) which features the MT2060 register map :
-
-   I2C Address : 0x60
-
-   Reg.No |   B7   |   B6   |   B5   |   B4   |   B3   |   B2   |   B1   |   B0   | ( defaults )
-   --------------------------------------------------------------------------------
-       00 | [              PART             ] | [              REV              ] | R  = 0x63
-       01 | [             LNABAND           ] | [              NUM1(5:2)        ] | RW = 0x3F
-       02 | [                               DIV1                                ] | RW = 0x74
-       03 | FM1CA  | FM1SS  | [  NUM1(1:0)  ] | [              NUM2(3:0)        ] | RW = 0x00
-       04 |                                 NUM2(11:4)                          ] | RW = 0x08
-       05 | [                               DIV2                       ] |NUM2(12)| RW = 0x93
-       06 | L1LK   | [        TAD1          ] | L2LK   | [         TAD2         ] | R
-       07 | [                               FMF                                 ] | R
-       08 |   ?    | FMCAL  |   ?    |   ?    |   ?    |   ?    |   ?    | TEMP   | R
-       09 |   0    |   0    | [    FMGC     ] |   0    | GP02   | GP01   |   0    | RW = 0x20
-       0A | ??
-       0B |   0    |   0    |   1    |   1    |   0    |   0    | [   VGAG      ] | RW = 0x30
-       0C | V1CSE  |   1    |   1    |   1    |   1    |   1    |   1    |   1    | RW = 0xFF
-       0D |   1    |   0    | [                      V1CS                       ] | RW = 0xB0
-       0E | ??
-       0F | ??
-       10 | ??
-       11 | [             LOTO              ] |   0    |   0    |   1    |   0    | RW = 0x42
-
-       PART    : Part code      : 6 for MT2060
-       REV     : Revision code  : 3 for current revision
-       LNABAND : Input frequency range : ( See code for details )
-       NUM1 / DIV1 / NUM2 / DIV2 : Frequencies programming ( See code for details )
-       FM1CA  : Calibration Start Bit
-       FM1SS  : Calibration Single Step bit
-       L1LK   : LO1 Lock Detect
-       TAD1   : Tune Line ADC ( ? )
-       L2LK   : LO2 Lock Detect
-       TAD2   : Tune Line ADC ( ? )
-       FMF    : Estimated first IF Center frequency Offset ( ? )
-       FM1CAL : Calibration done bit
-       TEMP   : On chip temperature sensor
-       FMCG   : Mixer 1 Cap Gain ( ? )
-       GP01 / GP02 : Programmable digital outputs. Unconnected pins ?
-       V1CSE  : LO1 VCO Automatic Capacitor Select Enable ( ? )
-       V1CS   : LO1 Capacitor Selection Value ( ? )
-       LOTO   : LO Timeout ( ? )
-       VGAG   : Tuner Output gain
-*/
-
-#define I2C_ADDRESS 0x60
-
-#define REG_PART_REV   0
-#define REG_LO1C1      1
-#define REG_LO1C2      2
-#define REG_LO2C1      3
-#define REG_LO2C2      4
-#define REG_LO2C3      5
-#define REG_LO_STATUS  6
-#define REG_FM_FREQ    7
-#define REG_MISC_STAT  8
-#define REG_MISC_CTRL  9
-#define REG_RESERVED_A 0x0A
-#define REG_VGAG       0x0B
-#define REG_LO1B1      0x0C
-#define REG_LO1B2      0x0D
-#define REG_LOTO       0x11
-
-#define PART_REV 0x63 // The current driver works only with PART=6 and REV=3 chips
-
-struct mt2060_priv {
-       struct mt2060_config *cfg;
-       struct i2c_adapter   *i2c;
-
-       u32 frequency;
-       u32 bandwidth;
-       u16 if1_freq;
-       u8  fmfreq;
-};
-
-#endif
 
+++ /dev/null
-/*
- *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
- *
- *  Copyright (c) 2006 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.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/dvb/frontend.h>
-#include <linux/i2c.h>
-
-#include "dvb_frontend.h"
-
-#include "mt2131.h"
-#include "mt2131_priv.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-#define dprintk(level,fmt, arg...) if (debug >= level) \
-       printk(KERN_INFO "%s: " fmt, "mt2131", ## arg)
-
-static u8 mt2131_config1[] = {
-       0x01,
-       0x50, 0x00, 0x50, 0x80, 0x00, 0x49, 0xfa, 0x88,
-       0x08, 0x77, 0x41, 0x04, 0x00, 0x00, 0x00, 0x32,
-       0x7f, 0xda, 0x4c, 0x00, 0x10, 0xaa, 0x78, 0x80,
-       0xff, 0x68, 0xa0, 0xff, 0xdd, 0x00, 0x00
-};
-
-static u8 mt2131_config2[] = {
-       0x10,
-       0x7f, 0xc8, 0x0a, 0x5f, 0x00, 0x04
-};
-
-static int mt2131_readreg(struct mt2131_priv *priv, u8 reg, u8 *val)
-{
-       struct i2c_msg msg[2] = {
-               { .addr = priv->cfg->i2c_address, .flags = 0,
-                 .buf = ®, .len = 1 },
-               { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
-                 .buf = val,  .len = 1 },
-       };
-
-       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
-               printk(KERN_WARNING "mt2131 I2C read failed\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int mt2131_writereg(struct mt2131_priv *priv, u8 reg, u8 val)
-{
-       u8 buf[2] = { reg, val };
-       struct i2c_msg msg = { .addr = priv->cfg->i2c_address, .flags = 0,
-                              .buf = buf, .len = 2 };
-
-       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
-               printk(KERN_WARNING "mt2131 I2C write failed\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int mt2131_writeregs(struct mt2131_priv *priv,u8 *buf, u8 len)
-{
-       struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
-                              .flags = 0, .buf = buf, .len = len };
-
-       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
-               printk(KERN_WARNING "mt2131 I2C write failed (len=%i)\n",
-                      (int)len);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-static int mt2131_set_params(struct dvb_frontend *fe,
-                            struct dvb_frontend_parameters *params)
-{
-       struct mt2131_priv *priv;
-       int ret=0, i;
-       u32 freq;
-       u8  if_band_center;
-       u32 f_lo1, f_lo2;
-       u32 div1, num1, div2, num2;
-       u8  b[8];
-       u8 lockval = 0;
-
-       priv = fe->tuner_priv;
-       if (fe->ops.info.type == FE_OFDM)
-               priv->bandwidth = params->u.ofdm.bandwidth;
-       else
-               priv->bandwidth = 0;
-
-       freq = params->frequency / 1000;  // Hz -> kHz
-       dprintk(1, "%s() freq=%d\n", __func__, freq);
-
-       f_lo1 = freq + MT2131_IF1 * 1000;
-       f_lo1 = (f_lo1 / 250) * 250;
-       f_lo2 = f_lo1 - freq - MT2131_IF2;
-
-       priv->frequency =  (f_lo1 - f_lo2 - MT2131_IF2) * 1000;
-
-       /* Frequency LO1 = 16MHz * (DIV1 + NUM1/8192 ) */
-       num1 = f_lo1 * 64 / (MT2131_FREF / 128);
-       div1 = num1 / 8192;
-       num1 &= 0x1fff;
-
-       /* Frequency LO2 = 16MHz * (DIV2 + NUM2/8192 ) */
-       num2 = f_lo2 * 64 / (MT2131_FREF / 128);
-       div2 = num2 / 8192;
-       num2 &= 0x1fff;
-
-       if (freq <=   82500) if_band_center = 0x00; else
-       if (freq <=  137500) if_band_center = 0x01; else
-       if (freq <=  192500) if_band_center = 0x02; else
-       if (freq <=  247500) if_band_center = 0x03; else
-       if (freq <=  302500) if_band_center = 0x04; else
-       if (freq <=  357500) if_band_center = 0x05; else
-       if (freq <=  412500) if_band_center = 0x06; else
-       if (freq <=  467500) if_band_center = 0x07; else
-       if (freq <=  522500) if_band_center = 0x08; else
-       if (freq <=  577500) if_band_center = 0x09; else
-       if (freq <=  632500) if_band_center = 0x0A; else
-       if (freq <=  687500) if_band_center = 0x0B; else
-       if (freq <=  742500) if_band_center = 0x0C; else
-       if (freq <=  797500) if_band_center = 0x0D; else
-       if (freq <=  852500) if_band_center = 0x0E; else
-       if (freq <=  907500) if_band_center = 0x0F; else
-       if (freq <=  962500) if_band_center = 0x10; else
-       if (freq <= 1017500) if_band_center = 0x11; else
-       if (freq <= 1072500) if_band_center = 0x12; else if_band_center = 0x13;
-
-       b[0] = 1;
-       b[1] = (num1 >> 5) & 0xFF;
-       b[2] = (num1 & 0x1F);
-       b[3] = div1;
-       b[4] = (num2 >> 5) & 0xFF;
-       b[5] = num2 & 0x1F;
-       b[6] = div2;
-
-       dprintk(1, "IF1: %dMHz IF2: %dMHz\n", MT2131_IF1, MT2131_IF2);
-       dprintk(1, "PLL freq=%dkHz  band=%d\n", (int)freq, (int)if_band_center);
-       dprintk(1, "PLL f_lo1=%dkHz  f_lo2=%dkHz\n", (int)f_lo1, (int)f_lo2);
-       dprintk(1, "PLL div1=%d  num1=%d  div2=%d  num2=%d\n",
-               (int)div1, (int)num1, (int)div2, (int)num2);
-       dprintk(1, "PLL [1..6]: %2x %2x %2x %2x %2x %2x\n",
-               (int)b[1], (int)b[2], (int)b[3], (int)b[4], (int)b[5],
-               (int)b[6]);
-
-       ret = mt2131_writeregs(priv,b,7);
-       if (ret < 0)
-               return ret;
-
-       mt2131_writereg(priv, 0x0b, if_band_center);
-
-       /* Wait for lock */
-       i = 0;
-       do {
-               mt2131_readreg(priv, 0x08, &lockval);
-               if ((lockval & 0x88) == 0x88)
-                       break;
-               msleep(4);
-               i++;
-       } while (i < 10);
-
-       return ret;
-}
-
-static int mt2131_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct mt2131_priv *priv = fe->tuner_priv;
-       dprintk(1, "%s()\n", __func__);
-       *frequency = priv->frequency;
-       return 0;
-}
-
-static int mt2131_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct mt2131_priv *priv = fe->tuner_priv;
-       dprintk(1, "%s()\n", __func__);
-       *bandwidth = priv->bandwidth;
-       return 0;
-}
-
-static int mt2131_get_status(struct dvb_frontend *fe, u32 *status)
-{
-       struct mt2131_priv *priv = fe->tuner_priv;
-       u8 lock_status = 0;
-       u8 afc_status = 0;
-
-       *status = 0;
-
-       mt2131_readreg(priv, 0x08, &lock_status);
-       if ((lock_status & 0x88) == 0x88)
-               *status = TUNER_STATUS_LOCKED;
-
-       mt2131_readreg(priv, 0x09, &afc_status);
-       dprintk(1, "%s() - LO Status = 0x%x, AFC Status = 0x%x\n",
-               __func__, lock_status, afc_status);
-
-       return 0;
-}
-
-static int mt2131_init(struct dvb_frontend *fe)
-{
-       struct mt2131_priv *priv = fe->tuner_priv;
-       int ret;
-       dprintk(1, "%s()\n", __func__);
-
-       if ((ret = mt2131_writeregs(priv, mt2131_config1,
-                                   sizeof(mt2131_config1))) < 0)
-               return ret;
-
-       mt2131_writereg(priv, 0x0b, 0x09);
-       mt2131_writereg(priv, 0x15, 0x47);
-       mt2131_writereg(priv, 0x07, 0xf2);
-       mt2131_writereg(priv, 0x0b, 0x01);
-
-       if ((ret = mt2131_writeregs(priv, mt2131_config2,
-                                   sizeof(mt2131_config2))) < 0)
-               return ret;
-
-       return ret;
-}
-
-static int mt2131_release(struct dvb_frontend *fe)
-{
-       dprintk(1, "%s()\n", __func__);
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static const struct dvb_tuner_ops mt2131_tuner_ops = {
-       .info = {
-               .name           = "Microtune MT2131",
-               .frequency_min  =  48000000,
-               .frequency_max  = 860000000,
-               .frequency_step =     50000,
-       },
-
-       .release       = mt2131_release,
-       .init          = mt2131_init,
-
-       .set_params    = mt2131_set_params,
-       .get_frequency = mt2131_get_frequency,
-       .get_bandwidth = mt2131_get_bandwidth,
-       .get_status    = mt2131_get_status
-};
-
-struct dvb_frontend * mt2131_attach(struct dvb_frontend *fe,
-                                   struct i2c_adapter *i2c,
-                                   struct mt2131_config *cfg, u16 if1)
-{
-       struct mt2131_priv *priv = NULL;
-       u8 id = 0;
-
-       dprintk(1, "%s()\n", __func__);
-
-       priv = kzalloc(sizeof(struct mt2131_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->cfg = cfg;
-       priv->bandwidth = 6000000; /* 6MHz */
-       priv->i2c = i2c;
-
-       if (mt2131_readreg(priv, 0, &id) != 0) {
-               kfree(priv);
-               return NULL;
-       }
-       if ( (id != 0x3E) && (id != 0x3F) ) {
-               printk(KERN_ERR "MT2131: Device not found at addr 0x%02x\n",
-                      cfg->i2c_address);
-               kfree(priv);
-               return NULL;
-       }
-
-       printk(KERN_INFO "MT2131: successfully identified at address 0x%02x\n",
-              cfg->i2c_address);
-       memcpy(&fe->ops.tuner_ops, &mt2131_tuner_ops,
-              sizeof(struct dvb_tuner_ops));
-
-       fe->tuner_priv = priv;
-       return fe;
-}
-EXPORT_SYMBOL(mt2131_attach);
-
-MODULE_AUTHOR("Steven Toth");
-MODULE_DESCRIPTION("Microtune MT2131 silicon tuner driver");
-MODULE_LICENSE("GPL");
-
-/*
- * Local variables:
- * c-basic-offset: 8
- */
 
+++ /dev/null
-/*
- *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
- *
- *  Copyright (c) 2006 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 __MT2131_H__
-#define __MT2131_H__
-
-struct dvb_frontend;
-struct i2c_adapter;
-
-struct mt2131_config {
-       u8 i2c_address;
-       u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
-};
-
-#if defined(CONFIG_DVB_TUNER_MT2131) || (defined(CONFIG_DVB_TUNER_MT2131_MODULE) && defined(MODULE))
-extern struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
-                                         struct i2c_adapter *i2c,
-                                         struct mt2131_config *cfg,
-                                         u16 if1);
-#else
-static inline struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
-                                                struct i2c_adapter *i2c,
-                                                struct mt2131_config *cfg,
-                                                u16 if1)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif /* CONFIG_DVB_TUNER_MT2131 */
-
-#endif /* __MT2131_H__ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- */
 
+++ /dev/null
-/*
- *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
- *
- *  Copyright (c) 2006 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 __MT2131_PRIV_H__
-#define __MT2131_PRIV_H__
-
-/* Regs */
-#define MT2131_PWR              0x07
-#define MT2131_UPC_1            0x0b
-#define MT2131_AGC_RL           0x10
-#define MT2131_MISC_2           0x15
-
-/* frequency values in KHz */
-#define MT2131_IF1              1220
-#define MT2131_IF2              44000
-#define MT2131_FREF             16000
-
-struct mt2131_priv {
-       struct mt2131_config *cfg;
-       struct i2c_adapter   *i2c;
-
-       u32 frequency;
-       u32 bandwidth;
-};
-
-#endif /* __MT2131_PRIV_H__ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- */
 
+++ /dev/null
-/*
- *  Driver for Microtune MT2266 "Direct conversion low power broadband tuner"
- *
- *  Copyright (c) 2007 Olivier DANET <odanet@caramail.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/dvb/frontend.h>
-#include <linux/i2c.h>
-
-#include "dvb_frontend.h"
-#include "mt2266.h"
-
-#define I2C_ADDRESS 0x60
-
-#define REG_PART_REV   0
-#define REG_TUNE       1
-#define REG_BAND       6
-#define REG_BANDWIDTH  8
-#define REG_LOCK       0x12
-
-#define PART_REV 0x85
-
-struct mt2266_priv {
-       struct mt2266_config *cfg;
-       struct i2c_adapter   *i2c;
-
-       u32 frequency;
-       u32 bandwidth;
-       u8 band;
-};
-
-#define MT2266_VHF 1
-#define MT2266_UHF 0
-
-/* Here, frequencies are expressed in kiloHertz to avoid 32 bits overflows */
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-#define dprintk(args...) do { if (debug) {printk(KERN_DEBUG "MT2266: " args); printk("\n"); }} while (0)
-
-// Reads a single register
-static int mt2266_readreg(struct mt2266_priv *priv, u8 reg, u8 *val)
-{
-       struct i2c_msg msg[2] = {
-               { .addr = priv->cfg->i2c_address, .flags = 0,        .buf = ®, .len = 1 },
-               { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val,  .len = 1 },
-       };
-       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
-               printk(KERN_WARNING "MT2266 I2C read failed\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-// Writes a single register
-static int mt2266_writereg(struct mt2266_priv *priv, u8 reg, u8 val)
-{
-       u8 buf[2] = { reg, val };
-       struct i2c_msg msg = {
-               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2
-       };
-       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
-               printk(KERN_WARNING "MT2266 I2C write failed\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-// Writes a set of consecutive registers
-static int mt2266_writeregs(struct mt2266_priv *priv,u8 *buf, u8 len)
-{
-       struct i2c_msg msg = {
-               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = len
-       };
-       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
-               printk(KERN_WARNING "MT2266 I2C write failed (len=%i)\n",(int)len);
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-// Initialisation sequences
-static u8 mt2266_init1[] = { REG_TUNE, 0x00, 0x00, 0x28,
-                                0x00, 0x52, 0x99, 0x3f };
-
-static u8 mt2266_init2[] = {
-    0x17, 0x6d, 0x71, 0x61, 0xc0, 0xbf, 0xff, 0xdc, 0x00, 0x0a, 0xd4,
-    0x03, 0x64, 0x64, 0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14,
-    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7f, 0x5e, 0x3f, 0xff, 0xff,
-    0xff, 0x00, 0x77, 0x0f, 0x2d
-};
-
-static u8 mt2266_init_8mhz[] = { REG_BANDWIDTH, 0x22, 0x22, 0x22, 0x22,
-                                               0x22, 0x22, 0x22, 0x22 };
-
-static u8 mt2266_init_7mhz[] = { REG_BANDWIDTH, 0x32, 0x32, 0x32, 0x32,
-                                               0x32, 0x32, 0x32, 0x32 };
-
-static u8 mt2266_init_6mhz[] = { REG_BANDWIDTH, 0xa7, 0xa7, 0xa7, 0xa7,
-                                               0xa7, 0xa7, 0xa7, 0xa7 };
-
-static u8 mt2266_uhf[] = { 0x1d, 0xdc, 0x00, 0x0a, 0xd4, 0x03, 0x64, 0x64,
-                          0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14 };
-
-static u8 mt2266_vhf[] = { 0x1d, 0xfe, 0x00, 0x00, 0xb4, 0x03, 0xa5, 0xa5,
-                          0xa5, 0xa5, 0x82, 0xaa, 0xf1, 0x17, 0x80, 0x1f };
-
-#define FREF 30000       // Quartz oscillator 30 MHz
-
-static int mt2266_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
-{
-       struct mt2266_priv *priv;
-       int ret=0;
-       u32 freq;
-       u32 tune;
-       u8  lnaband;
-       u8  b[10];
-       int i;
-       u8 band;
-
-       priv = fe->tuner_priv;
-
-       freq = params->frequency / 1000; // Hz -> kHz
-       if (freq < 470000 && freq > 230000)
-               return -EINVAL; /* Gap between VHF and UHF bands */
-       priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
-       priv->frequency = freq * 1000;
-
-       tune = 2 * freq * (8192/16) / (FREF/16);
-       band = (freq < 300000) ? MT2266_VHF : MT2266_UHF;
-       if (band == MT2266_VHF)
-               tune *= 2;
-
-       switch (params->u.ofdm.bandwidth) {
-       case BANDWIDTH_6_MHZ:
-               mt2266_writeregs(priv, mt2266_init_6mhz,
-                                sizeof(mt2266_init_6mhz));
-               break;
-       case BANDWIDTH_7_MHZ:
-               mt2266_writeregs(priv, mt2266_init_7mhz,
-                                sizeof(mt2266_init_7mhz));
-               break;
-       case BANDWIDTH_8_MHZ:
-       default:
-               mt2266_writeregs(priv, mt2266_init_8mhz,
-                                sizeof(mt2266_init_8mhz));
-               break;
-       }
-
-       if (band == MT2266_VHF && priv->band == MT2266_UHF) {
-               dprintk("Switch from UHF to VHF");
-               mt2266_writereg(priv, 0x05, 0x04);
-               mt2266_writereg(priv, 0x19, 0x61);
-               mt2266_writeregs(priv, mt2266_vhf, sizeof(mt2266_vhf));
-       } else if (band == MT2266_UHF && priv->band == MT2266_VHF) {
-               dprintk("Switch from VHF to UHF");
-               mt2266_writereg(priv, 0x05, 0x52);
-               mt2266_writereg(priv, 0x19, 0x61);
-               mt2266_writeregs(priv, mt2266_uhf, sizeof(mt2266_uhf));
-       }
-       msleep(10);
-
-       if (freq <= 495000)
-               lnaband = 0xEE;
-       else if (freq <= 525000)
-               lnaband = 0xDD;
-       else if (freq <= 550000)
-               lnaband = 0xCC;
-       else if (freq <= 580000)
-               lnaband = 0xBB;
-       else if (freq <= 605000)
-               lnaband = 0xAA;
-       else if (freq <= 630000)
-               lnaband = 0x99;
-       else if (freq <= 655000)
-               lnaband = 0x88;
-       else if (freq <= 685000)
-               lnaband = 0x77;
-       else if (freq <= 710000)
-               lnaband = 0x66;
-       else if (freq <= 735000)
-               lnaband = 0x55;
-       else if (freq <= 765000)
-               lnaband = 0x44;
-       else if (freq <= 802000)
-               lnaband = 0x33;
-       else if (freq <= 840000)
-               lnaband = 0x22;
-       else
-               lnaband = 0x11;
-
-       b[0] = REG_TUNE;
-       b[1] = (tune >> 8) & 0x1F;
-       b[2] = tune & 0xFF;
-       b[3] = tune >> 13;
-       mt2266_writeregs(priv,b,4);
-
-       dprintk("set_parms: tune=%d band=%d %s",
-               (int) tune, (int) lnaband,
-               (band == MT2266_UHF) ? "UHF" : "VHF");
-       dprintk("set_parms: [1..3]: %2x %2x %2x",
-               (int) b[1], (int) b[2], (int)b[3]);
-
-       if (band == MT2266_UHF) {
-               b[0] = 0x05;
-               b[1] = (priv->band == MT2266_VHF) ? 0x52 : 0x62;
-               b[2] = lnaband;
-               mt2266_writeregs(priv, b, 3);
-       }
-
-       /* Wait for pll lock or timeout */
-       i = 0;
-       do {
-               mt2266_readreg(priv,REG_LOCK,b);
-               if (b[0] & 0x40)
-                       break;
-               msleep(10);
-               i++;
-       } while (i<10);
-       dprintk("Lock when i=%i",(int)i);
-
-       if (band == MT2266_UHF && priv->band == MT2266_VHF)
-               mt2266_writereg(priv, 0x05, 0x62);
-
-       priv->band = band;
-
-       return ret;
-}
-
-static void mt2266_calibrate(struct mt2266_priv *priv)
-{
-       mt2266_writereg(priv, 0x11, 0x03);
-       mt2266_writereg(priv, 0x11, 0x01);
-       mt2266_writeregs(priv, mt2266_init1, sizeof(mt2266_init1));
-       mt2266_writeregs(priv, mt2266_init2, sizeof(mt2266_init2));
-       mt2266_writereg(priv, 0x33, 0x5e);
-       mt2266_writereg(priv, 0x10, 0x10);
-       mt2266_writereg(priv, 0x10, 0x00);
-       mt2266_writeregs(priv, mt2266_init_8mhz, sizeof(mt2266_init_8mhz));
-       msleep(25);
-       mt2266_writereg(priv, 0x17, 0x6d);
-       mt2266_writereg(priv, 0x1c, 0x00);
-       msleep(75);
-       mt2266_writereg(priv, 0x17, 0x6d);
-       mt2266_writereg(priv, 0x1c, 0xff);
-}
-
-static int mt2266_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct mt2266_priv *priv = fe->tuner_priv;
-       *frequency = priv->frequency;
-       return 0;
-}
-
-static int mt2266_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct mt2266_priv *priv = fe->tuner_priv;
-       *bandwidth = priv->bandwidth;
-       return 0;
-}
-
-static int mt2266_init(struct dvb_frontend *fe)
-{
-       int ret;
-       struct mt2266_priv *priv = fe->tuner_priv;
-       ret = mt2266_writereg(priv, 0x17, 0x6d);
-       if (ret < 0)
-               return ret;
-       ret = mt2266_writereg(priv, 0x1c, 0xff);
-       if (ret < 0)
-               return ret;
-       return 0;
-}
-
-static int mt2266_sleep(struct dvb_frontend *fe)
-{
-       struct mt2266_priv *priv = fe->tuner_priv;
-       mt2266_writereg(priv, 0x17, 0x6d);
-       mt2266_writereg(priv, 0x1c, 0x00);
-       return 0;
-}
-
-static int mt2266_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static const struct dvb_tuner_ops mt2266_tuner_ops = {
-       .info = {
-               .name           = "Microtune MT2266",
-               .frequency_min  = 174000000,
-               .frequency_max  = 862000000,
-               .frequency_step =     50000,
-       },
-       .release       = mt2266_release,
-       .init          = mt2266_init,
-       .sleep         = mt2266_sleep,
-       .set_params    = mt2266_set_params,
-       .get_frequency = mt2266_get_frequency,
-       .get_bandwidth = mt2266_get_bandwidth
-};
-
-struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg)
-{
-       struct mt2266_priv *priv = NULL;
-       u8 id = 0;
-
-       priv = kzalloc(sizeof(struct mt2266_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->cfg      = cfg;
-       priv->i2c      = i2c;
-       priv->band     = MT2266_UHF;
-
-       if (mt2266_readreg(priv, 0, &id)) {
-               kfree(priv);
-               return NULL;
-       }
-       if (id != PART_REV) {
-               kfree(priv);
-               return NULL;
-       }
-       printk(KERN_INFO "MT2266: successfully identified\n");
-       memcpy(&fe->ops.tuner_ops, &mt2266_tuner_ops, sizeof(struct dvb_tuner_ops));
-
-       fe->tuner_priv = priv;
-       mt2266_calibrate(priv);
-       return fe;
-}
-EXPORT_SYMBOL(mt2266_attach);
-
-MODULE_AUTHOR("Olivier DANET");
-MODULE_DESCRIPTION("Microtune MT2266 silicon tuner driver");
-MODULE_LICENSE("GPL");
 
+++ /dev/null
-/*
- *  Driver for Microtune MT2266 "Direct conversion low power broadband tuner"
- *
- *  Copyright (c) 2007 Olivier DANET <odanet@caramail.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- */
-
-#ifndef MT2266_H
-#define MT2266_H
-
-struct dvb_frontend;
-struct i2c_adapter;
-
-struct mt2266_config {
-       u8 i2c_address;
-};
-
-#if defined(CONFIG_DVB_TUNER_MT2266) || (defined(CONFIG_DVB_TUNER_MT2266_MODULE) && defined(MODULE))
-extern struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg);
-#else
-static inline struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_TUNER_MT2266
-
-#endif
 
+++ /dev/null
-/*
- *  Driver for Quantek QT1010 silicon tuner
- *
- *  Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
- *                     Aapo Tahkola <aet@rasterburn.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include "qt1010.h"
-#include "qt1010_priv.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "QT1010: " args); \
-       } while (0)
-
-/* read single register */
-static int qt1010_readreg(struct qt1010_priv *priv, u8 reg, u8 *val)
-{
-       struct i2c_msg msg[2] = {
-               { .addr = priv->cfg->i2c_address,
-                 .flags = 0, .buf = ®, .len = 1 },
-               { .addr = priv->cfg->i2c_address,
-                 .flags = I2C_M_RD, .buf = val, .len = 1 },
-       };
-
-       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
-               printk(KERN_WARNING "qt1010 I2C read failed\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-/* write single register */
-static int qt1010_writereg(struct qt1010_priv *priv, u8 reg, u8 val)
-{
-       u8 buf[2] = { reg, val };
-       struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
-                              .flags = 0, .buf = buf, .len = 2 };
-
-       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
-               printk(KERN_WARNING "qt1010 I2C write failed\n");
-               return -EREMOTEIO;
-       }
-       return 0;
-}
-
-/* dump all registers */
-static void qt1010_dump_regs(struct qt1010_priv *priv)
-{
-       char buf[52], buf2[4];
-       u8 reg, val;
-
-       for (reg = 0; ; reg++) {
-               if (reg % 16 == 0) {
-                       if (reg)
-                               printk("%s\n", buf);
-                       sprintf(buf, "%02x: ", reg);
-               }
-               if (qt1010_readreg(priv, reg, &val) == 0)
-                       sprintf(buf2, "%02x ", val);
-               else
-                       strcpy(buf2, "-- ");
-               strcat(buf, buf2);
-               if (reg == 0x2f)
-                       break;
-       }
-       printk("%s\n", buf);
-}
-
-static int qt1010_set_params(struct dvb_frontend *fe,
-                            struct dvb_frontend_parameters *params)
-{
-       struct qt1010_priv *priv;
-       int err;
-       u32 freq, div, mod1, mod2;
-       u8 i, tmpval, reg05;
-       qt1010_i2c_oper_t rd[48] = {
-               { QT1010_WR, 0x01, 0x80 },
-               { QT1010_WR, 0x02, 0x3f },
-               { QT1010_WR, 0x05, 0xff }, /* 02 c write */
-               { QT1010_WR, 0x06, 0x44 },
-               { QT1010_WR, 0x07, 0xff }, /* 04 c write */
-               { QT1010_WR, 0x08, 0x08 },
-               { QT1010_WR, 0x09, 0xff }, /* 06 c write */
-               { QT1010_WR, 0x0a, 0xff }, /* 07 c write */
-               { QT1010_WR, 0x0b, 0xff }, /* 08 c write */
-               { QT1010_WR, 0x0c, 0xe1 },
-               { QT1010_WR, 0x1a, 0xff }, /* 10 c write */
-               { QT1010_WR, 0x1b, 0x00 },
-               { QT1010_WR, 0x1c, 0x89 },
-               { QT1010_WR, 0x11, 0xff }, /* 13 c write */
-               { QT1010_WR, 0x12, 0xff }, /* 14 c write */
-               { QT1010_WR, 0x22, 0xff }, /* 15 c write */
-               { QT1010_WR, 0x1e, 0x00 },
-               { QT1010_WR, 0x1e, 0xd0 },
-               { QT1010_RD, 0x22, 0xff }, /* 16 c read */
-               { QT1010_WR, 0x1e, 0x00 },
-               { QT1010_RD, 0x05, 0xff }, /* 20 c read */
-               { QT1010_RD, 0x22, 0xff }, /* 21 c read */
-               { QT1010_WR, 0x23, 0xd0 },
-               { QT1010_WR, 0x1e, 0x00 },
-               { QT1010_WR, 0x1e, 0xe0 },
-               { QT1010_RD, 0x23, 0xff }, /* 25 c read */
-               { QT1010_RD, 0x23, 0xff }, /* 26 c read */
-               { QT1010_WR, 0x1e, 0x00 },
-               { QT1010_WR, 0x24, 0xd0 },
-               { QT1010_WR, 0x1e, 0x00 },
-               { QT1010_WR, 0x1e, 0xf0 },
-               { QT1010_RD, 0x24, 0xff }, /* 31 c read */
-               { QT1010_WR, 0x1e, 0x00 },
-               { QT1010_WR, 0x14, 0x7f },
-               { QT1010_WR, 0x15, 0x7f },
-               { QT1010_WR, 0x05, 0xff }, /* 35 c write */
-               { QT1010_WR, 0x06, 0x00 },
-               { QT1010_WR, 0x15, 0x1f },
-               { QT1010_WR, 0x16, 0xff },
-               { QT1010_WR, 0x18, 0xff },
-               { QT1010_WR, 0x1f, 0xff }, /* 40 c write */
-               { QT1010_WR, 0x20, 0xff }, /* 41 c write */
-               { QT1010_WR, 0x21, 0x53 },
-               { QT1010_WR, 0x25, 0xff }, /* 43 c write */
-               { QT1010_WR, 0x26, 0x15 },
-               { QT1010_WR, 0x00, 0xff }, /* 45 c write */
-               { QT1010_WR, 0x02, 0x00 },
-               { QT1010_WR, 0x01, 0x00 }
-       };
-
-#define FREQ1 32000000 /* 32 MHz */
-#define FREQ2  4000000 /* 4 MHz Quartz oscillator in the stick? */
-
-       priv = fe->tuner_priv;
-       freq = params->frequency;
-       div = (freq + QT1010_OFFSET) / QT1010_STEP;
-       freq = (div * QT1010_STEP) - QT1010_OFFSET;
-       mod1 = (freq + QT1010_OFFSET) % FREQ1;
-       mod2 = (freq + QT1010_OFFSET) % FREQ2;
-       priv->bandwidth =
-               (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
-       priv->frequency = freq;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
-
-       /* reg 05 base value */
-       if      (freq < 290000000) reg05 = 0x14; /* 290 MHz */
-       else if (freq < 610000000) reg05 = 0x34; /* 610 MHz */
-       else if (freq < 802000000) reg05 = 0x54; /* 802 MHz */
-       else                       reg05 = 0x74;
-
-       /* 0x5 */
-       rd[2].val = reg05;
-
-       /* 07 - set frequency: 32 MHz scale */
-       rd[4].val = (freq + QT1010_OFFSET) / FREQ1;
-
-       /* 09 - changes every 8/24 MHz */
-       if (mod1 < 8000000) rd[6].val = 0x1d;
-       else                rd[6].val = 0x1c;
-
-       /* 0a - set frequency: 4 MHz scale (max 28 MHz) */
-       if      (mod1 < 1*FREQ2) rd[7].val = 0x09; /*  +0 MHz */
-       else if (mod1 < 2*FREQ2) rd[7].val = 0x08; /*  +4 MHz */
-       else if (mod1 < 3*FREQ2) rd[7].val = 0x0f; /*  +8 MHz */
-       else if (mod1 < 4*FREQ2) rd[7].val = 0x0e; /* +12 MHz */
-       else if (mod1 < 5*FREQ2) rd[7].val = 0x0d; /* +16 MHz */
-       else if (mod1 < 6*FREQ2) rd[7].val = 0x0c; /* +20 MHz */
-       else if (mod1 < 7*FREQ2) rd[7].val = 0x0b; /* +24 MHz */
-       else                     rd[7].val = 0x0a; /* +28 MHz */
-
-       /* 0b - changes every 2/2 MHz */
-       if (mod2 < 2000000) rd[8].val = 0x45;
-       else                rd[8].val = 0x44;
-
-       /* 1a - set frequency: 125 kHz scale (max 3875 kHz)*/
-       tmpval = 0x78; /* byte, overflows intentionally */
-       rd[10].val = tmpval-((mod2/QT1010_STEP)*0x08);
-
-       /* 11 */
-       rd[13].val = 0xfd; /* TODO: correct value calculation */
-
-       /* 12 */
-       rd[14].val = 0x91; /* TODO: correct value calculation */
-
-       /* 22 */
-       if      (freq < 450000000) rd[15].val = 0xd0; /* 450 MHz */
-       else if (freq < 482000000) rd[15].val = 0xd1; /* 482 MHz */
-       else if (freq < 514000000) rd[15].val = 0xd4; /* 514 MHz */
-       else if (freq < 546000000) rd[15].val = 0xd7; /* 546 MHz */
-       else if (freq < 610000000) rd[15].val = 0xda; /* 610 MHz */
-       else                       rd[15].val = 0xd0;
-
-       /* 05 */
-       rd[35].val = (reg05 & 0xf0);
-
-       /* 1f */
-       if      (mod1 <  8000000) tmpval = 0x00;
-       else if (mod1 < 12000000) tmpval = 0x01;
-       else if (mod1 < 16000000) tmpval = 0x02;
-       else if (mod1 < 24000000) tmpval = 0x03;
-       else if (mod1 < 28000000) tmpval = 0x04;
-       else                      tmpval = 0x05;
-       rd[40].val = (priv->reg1f_init_val + 0x0e + tmpval);
-
-       /* 20 */
-       if      (mod1 <  8000000) tmpval = 0x00;
-       else if (mod1 < 12000000) tmpval = 0x01;
-       else if (mod1 < 20000000) tmpval = 0x02;
-       else if (mod1 < 24000000) tmpval = 0x03;
-       else if (mod1 < 28000000) tmpval = 0x04;
-       else                      tmpval = 0x05;
-       rd[41].val = (priv->reg20_init_val + 0x0d + tmpval);
-
-       /* 25 */
-       rd[43].val = priv->reg25_init_val;
-
-       /* 00 */
-       rd[45].val = 0x92; /* TODO: correct value calculation */
-
-       dprintk("freq:%u 05:%02x 07:%02x 09:%02x 0a:%02x 0b:%02x " \
-               "1a:%02x 11:%02x 12:%02x 22:%02x 05:%02x 1f:%02x " \
-               "20:%02x 25:%02x 00:%02x", \
-               freq, rd[2].val, rd[4].val, rd[6].val, rd[7].val, rd[8].val, \
-               rd[10].val, rd[13].val, rd[14].val, rd[15].val, rd[35].val, \
-               rd[40].val, rd[41].val, rd[43].val, rd[45].val);
-
-       for (i = 0; i < ARRAY_SIZE(rd); i++) {
-               if (rd[i].oper == QT1010_WR) {
-                       err = qt1010_writereg(priv, rd[i].reg, rd[i].val);
-               } else { /* read is required to proper locking */
-                       err = qt1010_readreg(priv, rd[i].reg, &tmpval);
-               }
-               if (err) return err;
-       }
-
-       if (debug)
-               qt1010_dump_regs(priv);
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
-
-       return 0;
-}
-
-static int qt1010_init_meas1(struct qt1010_priv *priv,
-                            u8 oper, u8 reg, u8 reg_init_val, u8 *retval)
-{
-       u8 i, val1, val2;
-       int err;
-
-       qt1010_i2c_oper_t i2c_data[] = {
-               { QT1010_WR, reg, reg_init_val },
-               { QT1010_WR, 0x1e, 0x00 },
-               { QT1010_WR, 0x1e, oper },
-               { QT1010_RD, reg, 0xff }
-       };
-
-       for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
-               if (i2c_data[i].oper == QT1010_WR) {
-                       err = qt1010_writereg(priv, i2c_data[i].reg,
-                                             i2c_data[i].val);
-               } else {
-                       err = qt1010_readreg(priv, i2c_data[i].reg, &val2);
-               }
-               if (err) return err;
-       }
-
-       do {
-               val1 = val2;
-               err = qt1010_readreg(priv, reg, &val2);
-               if (err) return err;
-               dprintk("compare reg:%02x %02x %02x", reg, val1, val2);
-       } while (val1 != val2);
-       *retval = val1;
-
-       return qt1010_writereg(priv, 0x1e, 0x00);
-}
-
-static u8 qt1010_init_meas2(struct qt1010_priv *priv,
-                           u8 reg_init_val, u8 *retval)
-{
-       u8 i, val;
-       int err;
-       qt1010_i2c_oper_t i2c_data[] = {
-               { QT1010_WR, 0x07, reg_init_val },
-               { QT1010_WR, 0x22, 0xd0 },
-               { QT1010_WR, 0x1e, 0x00 },
-               { QT1010_WR, 0x1e, 0xd0 },
-               { QT1010_RD, 0x22, 0xff },
-               { QT1010_WR, 0x1e, 0x00 },
-               { QT1010_WR, 0x22, 0xff }
-       };
-       for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
-               if (i2c_data[i].oper == QT1010_WR) {
-                       err = qt1010_writereg(priv, i2c_data[i].reg,
-                                             i2c_data[i].val);
-               } else {
-                       err = qt1010_readreg(priv, i2c_data[i].reg, &val);
-               }
-               if (err) return err;
-       }
-       *retval = val;
-       return 0;
-}
-
-static int qt1010_init(struct dvb_frontend *fe)
-{
-       struct qt1010_priv *priv = fe->tuner_priv;
-       struct dvb_frontend_parameters params;
-       int err = 0;
-       u8 i, tmpval, *valptr = NULL;
-
-       qt1010_i2c_oper_t i2c_data[] = {
-               { QT1010_WR, 0x01, 0x80 },
-               { QT1010_WR, 0x0d, 0x84 },
-               { QT1010_WR, 0x0e, 0xb7 },
-               { QT1010_WR, 0x2a, 0x23 },
-               { QT1010_WR, 0x2c, 0xdc },
-               { QT1010_M1, 0x25, 0x40 }, /* get reg 25 init value */
-               { QT1010_M1, 0x81, 0xff }, /* get reg 25 init value */
-               { QT1010_WR, 0x2b, 0x70 },
-               { QT1010_WR, 0x2a, 0x23 },
-               { QT1010_M1, 0x26, 0x08 },
-               { QT1010_M1, 0x82, 0xff },
-               { QT1010_WR, 0x05, 0x14 },
-               { QT1010_WR, 0x06, 0x44 },
-               { QT1010_WR, 0x07, 0x28 },
-               { QT1010_WR, 0x08, 0x0b },
-               { QT1010_WR, 0x11, 0xfd },
-               { QT1010_M1, 0x22, 0x0d },
-               { QT1010_M1, 0xd0, 0xff },
-               { QT1010_WR, 0x06, 0x40 },
-               { QT1010_WR, 0x16, 0xf0 },
-               { QT1010_WR, 0x02, 0x38 },
-               { QT1010_WR, 0x03, 0x18 },
-               { QT1010_WR, 0x20, 0xe0 },
-               { QT1010_M1, 0x1f, 0x20 }, /* get reg 1f init value */
-               { QT1010_M1, 0x84, 0xff }, /* get reg 1f init value */
-               { QT1010_RD, 0x20, 0x20 }, /* get reg 20 init value */
-               { QT1010_WR, 0x03, 0x19 },
-               { QT1010_WR, 0x02, 0x3f },
-               { QT1010_WR, 0x21, 0x53 },
-               { QT1010_RD, 0x21, 0xff },
-               { QT1010_WR, 0x11, 0xfd },
-               { QT1010_WR, 0x05, 0x34 },
-               { QT1010_WR, 0x06, 0x44 },
-               { QT1010_WR, 0x08, 0x08 }
-       };
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
-
-       for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
-               switch (i2c_data[i].oper) {
-               case QT1010_WR:
-                       err = qt1010_writereg(priv, i2c_data[i].reg,
-                                             i2c_data[i].val);
-                       break;
-               case QT1010_RD:
-                       if (i2c_data[i].val == 0x20)
-                               valptr = &priv->reg20_init_val;
-                       else
-                               valptr = &tmpval;
-                       err = qt1010_readreg(priv, i2c_data[i].reg, valptr);
-                       break;
-               case QT1010_M1:
-                       if (i2c_data[i].val == 0x25)
-                               valptr = &priv->reg25_init_val;
-                       else if (i2c_data[i].val == 0x1f)
-                               valptr = &priv->reg1f_init_val;
-                       else
-                               valptr = &tmpval;
-                       err = qt1010_init_meas1(priv, i2c_data[i+1].reg,
-                                               i2c_data[i].reg,
-                                               i2c_data[i].val, valptr);
-                       i++;
-                       break;
-               }
-               if (err) return err;
-       }
-
-       for (i = 0x31; i < 0x3a; i++) /* 0x31 - 0x39 */
-               if ((err = qt1010_init_meas2(priv, i, &tmpval)))
-                       return err;
-
-       params.frequency = 545000000; /* Sigmatek DVB-110 545000000 */
-                                     /* MSI Megasky 580 GL861 533000000 */
-       return qt1010_set_params(fe, ¶ms);
-}
-
-static int qt1010_release(struct dvb_frontend *fe)
-{
-       kfree(fe->tuner_priv);
-       fe->tuner_priv = NULL;
-       return 0;
-}
-
-static int qt1010_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
-       struct qt1010_priv *priv = fe->tuner_priv;
-       *frequency = priv->frequency;
-       return 0;
-}
-
-static int qt1010_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
-       struct qt1010_priv *priv = fe->tuner_priv;
-       *bandwidth = priv->bandwidth;
-       return 0;
-}
-
-static const struct dvb_tuner_ops qt1010_tuner_ops = {
-       .info = {
-               .name           = "Quantek QT1010",
-               .frequency_min  = QT1010_MIN_FREQ,
-               .frequency_max  = QT1010_MAX_FREQ,
-               .frequency_step = QT1010_STEP,
-       },
-
-       .release       = qt1010_release,
-       .init          = qt1010_init,
-       /* TODO: implement sleep */
-
-       .set_params    = qt1010_set_params,
-       .get_frequency = qt1010_get_frequency,
-       .get_bandwidth = qt1010_get_bandwidth
-};
-
-struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe,
-                                   struct i2c_adapter *i2c,
-                                   struct qt1010_config *cfg)
-{
-       struct qt1010_priv *priv = NULL;
-       u8 id;
-
-       priv = kzalloc(sizeof(struct qt1010_priv), GFP_KERNEL);
-       if (priv == NULL)
-               return NULL;
-
-       priv->cfg = cfg;
-       priv->i2c = i2c;
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
-
-
-       /* Try to detect tuner chip. Probably this is not correct register. */
-       if (qt1010_readreg(priv, 0x29, &id) != 0 || (id != 0x39)) {
-               kfree(priv);
-               return NULL;
-       }
-
-       if (fe->ops.i2c_gate_ctrl)
-               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
-
-       printk(KERN_INFO "Quantek QT1010 successfully identified.\n");
-       memcpy(&fe->ops.tuner_ops, &qt1010_tuner_ops,
-              sizeof(struct dvb_tuner_ops));
-
-       fe->tuner_priv = priv;
-       return fe;
-}
-EXPORT_SYMBOL(qt1010_attach);
-
-MODULE_DESCRIPTION("Quantek QT1010 silicon tuner driver");
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>");
-MODULE_VERSION("0.1");
-MODULE_LICENSE("GPL");
 
+++ /dev/null
-/*
- *  Driver for Quantek QT1010 silicon tuner
- *
- *  Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
- *                     Aapo Tahkola <aet@rasterburn.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef QT1010_H
-#define QT1010_H
-
-#include "dvb_frontend.h"
-
-struct qt1010_config {
-       u8 i2c_address;
-};
-
-/**
- * Attach a qt1010 tuner to the supplied frontend structure.
- *
- * @param fe   frontend to attach to
- * @param i2c  i2c adapter to use
- * @param cfg  tuner hw based configuration
- * @return fe  pointer on success, NULL on failure
- */
-#if defined(CONFIG_DVB_TUNER_QT1010) || (defined(CONFIG_DVB_TUNER_QT1010_MODULE) && defined(MODULE))
-extern struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe,
-                                         struct i2c_adapter *i2c,
-                                         struct qt1010_config *cfg);
-#else
-static inline struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe,
-                                                struct i2c_adapter *i2c,
-                                                struct qt1010_config *cfg)
-{
-       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-       return NULL;
-}
-#endif // CONFIG_DVB_TUNER_QT1010
-
-#endif
 
+++ /dev/null
-/*
- *  Driver for Quantek QT1010 silicon tuner
- *
- *  Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
- *                     Aapo Tahkola <aet@rasterburn.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef QT1010_PRIV_H
-#define QT1010_PRIV_H
-
-/*
-reg def meaning
-=== === =======
-00  00  ?
-01  a0  ? operation start/stop; start=80, stop=00
-02  00  ?
-03  19  ?
-04  00  ?
-05  00  ? maybe band selection
-06  00  ?
-07  2b  set frequency: 32 MHz scale, n*32 MHz
-08  0b  ?
-09  10  ? changes every 8/24 MHz; values 1d/1c
-0a  08  set frequency: 4 MHz scale, n*4 MHz
-0b  41  ? changes every 2/2 MHz; values 45/45
-0c  e1  ?
-0d  94  ?
-0e  b6  ?
-0f  2c  ?
-10  10  ?
-11  f1  ? maybe device specified adjustment
-12  11  ? maybe device specified adjustment
-13  3f  ?
-14  1f  ?
-15  3f  ?
-16  ff  ?
-17  ff  ?
-18  f7  ?
-19  80  ?
-1a  d0  set frequency: 125 kHz scale, n*125 kHz
-1b  00  ?
-1c  89  ?
-1d  00  ?
-1e  00  ? looks like operation register; write cmd here, read result from 1f-26
-1f  20  ? chip initialization
-20  e0  ? chip initialization
-21  20  ?
-22  d0  ?
-23  d0  ?
-24  d0  ?
-25  40  ? chip initialization
-26  08  ?
-27  29  ?
-28  55  ?
-29  39  ?
-2a  13  ?
-2b  01  ?
-2c  ea  ?
-2d  00  ?
-2e  00  ? not used?
-2f  00  ? not used?
-*/
-
-#define QT1010_STEP         125000 /*  125 kHz used by Windows drivers,
-                                     hw could be more precise but we don't
-                                     know how to use */
-#define QT1010_MIN_FREQ   48000000 /*   48 MHz */
-#define QT1010_MAX_FREQ  860000000 /*  860 MHz */
-#define QT1010_OFFSET   1246000000 /* 1246 MHz */
-
-#define QT1010_WR 0
-#define QT1010_RD 1
-#define QT1010_M1 3
-
-typedef struct {
-       u8 oper, reg, val;
-} qt1010_i2c_oper_t;
-
-struct qt1010_priv {
-       struct qt1010_config *cfg;
-       struct i2c_adapter   *i2c;
-
-       u8 reg1f_init_val;
-       u8 reg20_init_val;
-       u8 reg25_init_val;
-
-       u32 frequency;
-       u32 bandwidth;
-};
-
-#endif