include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / media / video / saa7134 / saa7134-dvb.c
index 7fa6ce7..4ab4a98 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
 #include <linux/suspend.h>
@@ -40,6 +39,7 @@
 #include "tda1004x.h"
 #include "nxt200x.h"
 #include "tuner-xc2028.h"
+#include "xc5000.h"
 
 #include "tda10086.h"
 #include "tda826x.h"
 #include "isl6405.h"
 #include "lnbp21.h"
 #include "tuner-simple.h"
+#include "tda10048.h"
+#include "tda18271.h"
+#include "lgdt3305.h"
+#include "tda8290.h"
+
+#include "zl10353.h"
+
+#include "zl10036.h"
+#include "zl10039.h"
+#include "mt312.h"
 
 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
 MODULE_LICENSE("GPL");
@@ -187,7 +197,7 @@ static int mt352_pinnacle_tuner_set_params(struct dvb_frontend* fe,
        if (fe->ops.i2c_gate_ctrl)
                fe->ops.i2c_gate_ctrl(fe, 1);
        i2c_transfer(&dev->i2c_adap, &msg, 1);
-       saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
+       saa_call_all(dev, tuner, s_frequency, &f);
        msg.buf = on;
        if (fe->ops.i2c_gate_ctrl)
                fe->ops.i2c_gate_ctrl(fe, 1);
@@ -535,11 +545,16 @@ static int configure_tda827x_fe(struct saa7134_dev *dev,
                                struct tda1004x_config *cdec_conf,
                                struct tda827x_config *tuner_conf)
 {
-       dev->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap);
-       if (dev->dvb.frontend) {
+       struct videobuf_dvb_frontend *fe0;
+
+       /* Get the first frontend */
+       fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
+
+       fe0->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap);
+       if (fe0->dvb.frontend) {
                if (cdec_conf->i2c_gate)
-                       dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
-               if (dvb_attach(tda827x_attach, dev->dvb.frontend,
+                       fe0->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
+               if (dvb_attach(tda827x_attach, fe0->dvb.frontend,
                               cdec_conf->tuner_address,
                               &dev->i2c_adap, tuner_conf))
                        return 0;
@@ -553,7 +568,6 @@ static int configure_tda827x_fe(struct saa7134_dev *dev,
 /* ------------------------------------------------------------------ */
 
 static struct tda827x_config tda827x_cfg_0 = {
-       .tuner_callback = saa7134_tuner_callback,
        .init = philips_tda827x_tuner_init,
        .sleep = philips_tda827x_tuner_sleep,
        .config = 0,
@@ -561,7 +575,6 @@ static struct tda827x_config tda827x_cfg_0 = {
 };
 
 static struct tda827x_config tda827x_cfg_1 = {
-       .tuner_callback = saa7134_tuner_callback,
        .init = philips_tda827x_tuner_init,
        .sleep = philips_tda827x_tuner_sleep,
        .config = 1,
@@ -569,7 +582,6 @@ static struct tda827x_config tda827x_cfg_1 = {
 };
 
 static struct tda827x_config tda827x_cfg_2 = {
-       .tuner_callback = saa7134_tuner_callback,
        .init = philips_tda827x_tuner_init,
        .sleep = philips_tda827x_tuner_sleep,
        .config = 2,
@@ -577,7 +589,6 @@ static struct tda827x_config tda827x_cfg_2 = {
 };
 
 static struct tda827x_config tda827x_cfg_2_sw42 = {
-       .tuner_callback = saa7134_tuner_callback,
        .init = philips_tda827x_tuner_init,
        .sleep = philips_tda827x_tuner_sleep,
        .config = 2,
@@ -836,7 +847,6 @@ static int ads_duo_tuner_sleep(struct dvb_frontend *fe)
 }
 
 static struct tda827x_config ads_duo_cfg = {
-       .tuner_callback = saa7134_tuner_callback,
        .init = ads_duo_tuner_init,
        .sleep = ads_duo_tuner_sleep,
        .config = 0
@@ -854,6 +864,27 @@ static struct tda1004x_config ads_tech_duo_config = {
        .request_firmware = philips_tda1004x_request_firmware
 };
 
+static struct zl10353_config behold_h6_config = {
+       .demod_address = 0x1e>>1,
+       .no_tuner      = 1,
+       .parallel_ts   = 1,
+       .disable_i2c_gate_ctrl = 1,
+};
+
+static struct xc5000_config behold_x7_tunerconfig = {
+       .i2c_address      = 0xc2>>1,
+       .if_khz           = 4560,
+       .radio_input      = XC5000_RADIO_FM1,
+};
+
+static struct zl10353_config behold_x7_config = {
+       .demod_address = 0x1e>>1,
+       .if2           = 45600,
+       .no_tuner      = 1,
+       .parallel_ts   = 1,
+       .disable_i2c_gate_ctrl = 1,
+};
+
 /* ==================================================================
  * tda10086 based DVB-S cards, helper functions
  */
@@ -941,6 +972,104 @@ static struct nxt200x_config kworldatsc110 = {
        .demod_address    = 0x0a,
 };
 
+/* ------------------------------------------------------------------ */
+
+static struct mt312_config avertv_a700_mt312 = {
+       .demod_address = 0x0e,
+       .voltage_inverted = 1,
+};
+
+static struct zl10036_config avertv_a700_tuner = {
+       .tuner_address = 0x60,
+};
+
+static struct mt312_config zl10313_compro_s350_config = {
+       .demod_address = 0x0e,
+};
+
+static struct lgdt3305_config hcw_lgdt3305_config = {
+       .i2c_addr           = 0x0e,
+       .mpeg_mode          = LGDT3305_MPEG_SERIAL,
+       .tpclk_edge         = LGDT3305_TPCLK_RISING_EDGE,
+       .tpvalid_polarity   = LGDT3305_TP_VALID_HIGH,
+       .deny_i2c_rptr      = 1,
+       .spectral_inversion = 1,
+       .qam_if_khz         = 4000,
+       .vsb_if_khz         = 3250,
+};
+
+static struct tda10048_config hcw_tda10048_config = {
+       .demod_address    = 0x10 >> 1,
+       .output_mode      = TDA10048_SERIAL_OUTPUT,
+       .fwbulkwritelen   = TDA10048_BULKWRITE_200,
+       .inversion        = TDA10048_INVERSION_ON,
+       .dtv6_if_freq_khz = TDA10048_IF_3300,
+       .dtv7_if_freq_khz = TDA10048_IF_3500,
+       .dtv8_if_freq_khz = TDA10048_IF_4000,
+       .clk_freq_khz     = TDA10048_CLK_16000,
+       .disable_gate_access = 1,
+};
+
+static struct tda18271_std_map hauppauge_tda18271_std_map = {
+       .atsc_6   = { .if_freq = 3250, .agc_mode = 3, .std = 4,
+                     .if_lvl = 1, .rfagc_top = 0x58, },
+       .qam_6    = { .if_freq = 4000, .agc_mode = 3, .std = 5,
+                     .if_lvl = 1, .rfagc_top = 0x58, },
+};
+
+static struct tda18271_config hcw_tda18271_config = {
+       .std_map = &hauppauge_tda18271_std_map,
+       .gate    = TDA18271_GATE_ANALOG,
+       .config  = 3,
+       .output_opt = TDA18271_OUTPUT_LT_OFF,
+};
+
+static struct tda829x_config tda829x_no_probe = {
+       .probe_tuner = TDA829X_DONT_PROBE,
+};
+
+static struct tda10048_config zolid_tda10048_config = {
+       .demod_address    = 0x10 >> 1,
+       .output_mode      = TDA10048_PARALLEL_OUTPUT,
+       .fwbulkwritelen   = TDA10048_BULKWRITE_200,
+       .inversion        = TDA10048_INVERSION_ON,
+       .dtv6_if_freq_khz = TDA10048_IF_3300,
+       .dtv7_if_freq_khz = TDA10048_IF_3500,
+       .dtv8_if_freq_khz = TDA10048_IF_4000,
+       .clk_freq_khz     = TDA10048_CLK_16000,
+       .disable_gate_access = 1,
+};
+
+static struct tda18271_config zolid_tda18271_config = {
+       .gate    = TDA18271_GATE_ANALOG,
+};
+
+static struct tda10048_config dtv1000s_tda10048_config = {
+       .demod_address    = 0x10 >> 1,
+       .output_mode      = TDA10048_PARALLEL_OUTPUT,
+       .fwbulkwritelen   = TDA10048_BULKWRITE_200,
+       .inversion        = TDA10048_INVERSION_ON,
+       .dtv6_if_freq_khz = TDA10048_IF_3300,
+       .dtv7_if_freq_khz = TDA10048_IF_3800,
+       .dtv8_if_freq_khz = TDA10048_IF_4300,
+       .clk_freq_khz     = TDA10048_CLK_16000,
+       .disable_gate_access = 1,
+};
+
+static struct tda18271_std_map dtv1000s_tda18271_std_map = {
+       .dvbt_6   = { .if_freq = 3300, .agc_mode = 3, .std = 4,
+                     .if_lvl = 1, .rfagc_top = 0x37, },
+       .dvbt_7   = { .if_freq = 3800, .agc_mode = 3, .std = 5,
+                     .if_lvl = 1, .rfagc_top = 0x37, },
+       .dvbt_8   = { .if_freq = 4300, .agc_mode = 3, .std = 6,
+                     .if_lvl = 1, .rfagc_top = 0x37, },
+};
+
+static struct tda18271_config dtv1000s_tda18271_config = {
+       .std_map = &dtv1000s_tda18271_std_map,
+       .gate    = TDA18271_GATE_ANALOG,
+};
+
 /* ==================================================================
  * Core code
  */
@@ -949,12 +1078,24 @@ static int dvb_init(struct saa7134_dev *dev)
 {
        int ret;
        int attach_xc3028 = 0;
+       struct videobuf_dvb_frontend *fe0;
+
+       /* FIXME: add support for multi-frontend */
+       mutex_init(&dev->frontends.lock);
+       INIT_LIST_HEAD(&dev->frontends.felist);
+
+       printk(KERN_INFO "%s() allocating 1 frontend\n", __func__);
+       fe0 = videobuf_dvb_alloc_frontend(&dev->frontends, 1);
+       if (!fe0) {
+               printk(KERN_ERR "%s() failed to alloc\n", __func__);
+               return -ENOMEM;
+       }
 
        /* init struct videobuf_dvb */
        dev->ts.nr_bufs    = 32;
        dev->ts.nr_packets = 32*4;
-       dev->dvb.name = dev->name;
-       videobuf_queue_sg_init(&dev->dvb.dvbq, &saa7134_ts_qops,
+       fe0->dvb.name = dev->name;
+       videobuf_queue_sg_init(&fe0->dvb.dvbq, &saa7134_ts_qops,
                            &dev->pci->dev, &dev->slock,
                            V4L2_BUF_TYPE_VIDEO_CAPTURE,
                            V4L2_FIELD_ALTERNATE,
@@ -964,47 +1105,47 @@ static int dvb_init(struct saa7134_dev *dev)
        switch (dev->board) {
        case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
                dprintk("pinnacle 300i dvb setup\n");
-               dev->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i,
+               fe0->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i,
                                               &dev->i2c_adap);
-               if (dev->dvb.frontend) {
-                       dev->dvb.frontend->ops.tuner_ops.set_params = mt352_pinnacle_tuner_set_params;
+               if (fe0->dvb.frontend) {
+                       fe0->dvb.frontend->ops.tuner_ops.set_params = mt352_pinnacle_tuner_set_params;
                }
                break;
        case SAA7134_BOARD_AVERMEDIA_777:
        case SAA7134_BOARD_AVERMEDIA_A16AR:
                dprintk("avertv 777 dvb setup\n");
-               dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777,
+               fe0->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777,
                                               &dev->i2c_adap);
-               if (dev->dvb.frontend) {
-                       dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+               if (fe0->dvb.frontend) {
+                       dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
                                   &dev->i2c_adap, 0x61,
                                   TUNER_PHILIPS_TD1316);
                }
                break;
        case SAA7134_BOARD_AVERMEDIA_A16D:
                dprintk("AverMedia A16D dvb setup\n");
-               dev->dvb.frontend = dvb_attach(mt352_attach,
+               fe0->dvb.frontend = dvb_attach(mt352_attach,
                                                &avermedia_xc3028_mt352_dev,
                                                &dev->i2c_adap);
                attach_xc3028 = 1;
                break;
        case SAA7134_BOARD_MD7134:
-               dev->dvb.frontend = dvb_attach(tda10046_attach,
+               fe0->dvb.frontend = dvb_attach(tda10046_attach,
                                               &medion_cardbus,
                                               &dev->i2c_adap);
-               if (dev->dvb.frontend) {
-                       dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+               if (fe0->dvb.frontend) {
+                       dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
                                   &dev->i2c_adap, medion_cardbus.tuner_address,
                                   TUNER_PHILIPS_FMD1216ME_MK3);
                }
                break;
        case SAA7134_BOARD_PHILIPS_TOUGH:
-               dev->dvb.frontend = dvb_attach(tda10046_attach,
+               fe0->dvb.frontend = dvb_attach(tda10046_attach,
                                               &philips_tu1216_60_config,
                                               &dev->i2c_adap);
-               if (dev->dvb.frontend) {
-                       dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
-                       dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
+               if (fe0->dvb.frontend) {
+                       fe0->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
+                       fe0->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
                }
                break;
        case SAA7134_BOARD_FLYDVBTDUO:
@@ -1015,24 +1156,25 @@ static int dvb_init(struct saa7134_dev *dev)
                break;
        case SAA7134_BOARD_PHILIPS_EUROPA:
        case SAA7134_BOARD_VIDEOMATE_DVBT_300:
-               dev->dvb.frontend = dvb_attach(tda10046_attach,
+       case SAA7134_BOARD_ASUS_EUROPA_HYBRID:
+               fe0->dvb.frontend = dvb_attach(tda10046_attach,
                                               &philips_europa_config,
                                               &dev->i2c_adap);
-               if (dev->dvb.frontend) {
-                       dev->original_demod_sleep = dev->dvb.frontend->ops.sleep;
-                       dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
-                       dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init;
-                       dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep;
-                       dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
+               if (fe0->dvb.frontend) {
+                       dev->original_demod_sleep = fe0->dvb.frontend->ops.sleep;
+                       fe0->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
+                       fe0->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init;
+                       fe0->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep;
+                       fe0->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
                }
                break;
        case SAA7134_BOARD_VIDEOMATE_DVBT_200:
-               dev->dvb.frontend = dvb_attach(tda10046_attach,
+               fe0->dvb.frontend = dvb_attach(tda10046_attach,
                                               &philips_tu1216_61_config,
                                               &dev->i2c_adap);
-               if (dev->dvb.frontend) {
-                       dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
-                       dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
+               if (fe0->dvb.frontend) {
+                       fe0->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
+                       fe0->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
                }
                break;
        case SAA7134_BOARD_KWORLD_DVBT_210:
@@ -1040,6 +1182,19 @@ static int dvb_init(struct saa7134_dev *dev)
                                         &tda827x_cfg_2) < 0)
                        goto dettach_frontend;
                break;
+       case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+               fe0->dvb.frontend = dvb_attach(tda10048_attach,
+                                              &hcw_tda10048_config,
+                                              &dev->i2c_adap);
+               if (fe0->dvb.frontend != NULL) {
+                       dvb_attach(tda829x_attach, fe0->dvb.frontend,
+                                  &dev->i2c_adap, 0x4b,
+                                  &tda829x_no_probe);
+                       dvb_attach(tda18271_attach, fe0->dvb.frontend,
+                                  0x60, &dev->i2c_adap,
+                                  &hcw_tda18271_config);
+               }
+               break;
        case SAA7134_BOARD_PHILIPS_TIGER:
                if (configure_tda827x_fe(dev, &philips_tiger_config,
                                         &tda827x_cfg_0) < 0)
@@ -1055,6 +1210,19 @@ static int dvb_init(struct saa7134_dev *dev)
                                         &tda827x_cfg_1) < 0)
                        goto dettach_frontend;
                break;
+       case SAA7134_BOARD_HAUPPAUGE_HVR1150:
+               fe0->dvb.frontend = dvb_attach(lgdt3305_attach,
+                                              &hcw_lgdt3305_config,
+                                              &dev->i2c_adap);
+               if (fe0->dvb.frontend) {
+                       dvb_attach(tda829x_attach, fe0->dvb.frontend,
+                                  &dev->i2c_adap, 0x4b,
+                                  &tda829x_no_probe);
+                       dvb_attach(tda18271_attach, fe0->dvb.frontend,
+                                  0x60, &dev->i2c_adap,
+                                  &hcw_tda18271_config);
+               }
+               break;
        case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
                if (configure_tda827x_fe(dev, &asus_p7131_dual_config,
                                         &tda827x_cfg_0) < 0)
@@ -1071,14 +1239,14 @@ static int dvb_init(struct saa7134_dev *dev)
                                                 &tda827x_cfg_0) < 0)
                                goto dettach_frontend;
                } else {                /* satellite */
-                       dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
-                       if (dev->dvb.frontend) {
-                               if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63,
+                       fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
+                       if (fe0->dvb.frontend) {
+                               if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x63,
                                                                        &dev->i2c_adap, 0) == NULL) {
                                        wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__);
                                        goto dettach_frontend;
                                }
-                               if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap,
+                               if (dvb_attach(isl6421_attach, fe0->dvb.frontend, &dev->i2c_adap,
                                                                                0x08, 0, 0) == NULL) {
                                        wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__);
                                        goto dettach_frontend;
@@ -1088,11 +1256,11 @@ static int dvb_init(struct saa7134_dev *dev)
                break;
        case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
        case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
-               dev->dvb.frontend = dvb_attach(tda10046_attach,
+               fe0->dvb.frontend = dvb_attach(tda10046_attach,
                                               &ads_tech_duo_config,
                                               &dev->i2c_adap);
-               if (dev->dvb.frontend) {
-                       if (dvb_attach(tda827x_attach,dev->dvb.frontend,
+               if (fe0->dvb.frontend) {
+                       if (dvb_attach(tda827x_attach,fe0->dvb.frontend,
                                   ads_tech_duo_config.tuner_address, &dev->i2c_adap,
                                                                &ads_duo_cfg) == NULL) {
                                wprintk("no tda827x tuner found at addr: %02x\n",
@@ -1113,15 +1281,15 @@ static int dvb_init(struct saa7134_dev *dev)
                                                 &tda827x_cfg_0) < 0)
                                goto dettach_frontend;
                } else {        /* satellite */
-                       dev->dvb.frontend = dvb_attach(tda10086_attach,
+                       fe0->dvb.frontend = dvb_attach(tda10086_attach,
                                                        &flydvbs, &dev->i2c_adap);
-                       if (dev->dvb.frontend) {
-                               struct dvb_frontend *fe = dev->dvb.frontend;
+                       if (fe0->dvb.frontend) {
+                               struct dvb_frontend *fe = fe0->dvb.frontend;
                                u8 dev_id = dev->eedata[2];
                                u8 data = 0xc4;
                                struct i2c_msg msg = {.addr = 0x08, .flags = 0, .len = 1};
 
-                               if (dvb_attach(tda826x_attach, dev->dvb.frontend,
+                               if (dvb_attach(tda826x_attach, fe0->dvb.frontend,
                                                0x60, &dev->i2c_adap, 0) == NULL) {
                                        wprintk("%s: Medion Quadro, no tda826x "
                                                "found !\n", __func__);
@@ -1155,30 +1323,31 @@ static int dvb_init(struct saa7134_dev *dev)
                }
                break;
        case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
-               dev->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180,
+               fe0->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180,
                                               &dev->i2c_adap);
-               if (dev->dvb.frontend)
-                       dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+               if (fe0->dvb.frontend)
+                       dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x61,
                                   NULL, DVB_PLL_TDHU2);
                break;
+       case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
        case SAA7134_BOARD_KWORLD_ATSC110:
-               dev->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110,
+               fe0->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110,
                                               &dev->i2c_adap);
-               if (dev->dvb.frontend)
-                       dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+               if (fe0->dvb.frontend)
+                       dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
                                   &dev->i2c_adap, 0x61,
                                   TUNER_PHILIPS_TUV1236D);
                break;
        case SAA7134_BOARD_FLYDVBS_LR300:
-               dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
+               fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
                                               &dev->i2c_adap);
-               if (dev->dvb.frontend) {
-                       if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
+               if (fe0->dvb.frontend) {
+                       if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60,
                                       &dev->i2c_adap, 0) == NULL) {
                                wprintk("%s: No tda826x found!\n", __func__);
                                goto dettach_frontend;
                        }
-                       if (dvb_attach(isl6421_attach, dev->dvb.frontend,
+                       if (dvb_attach(isl6421_attach, fe0->dvb.frontend,
                                       &dev->i2c_adap, 0x08, 0, 0) == NULL) {
                                wprintk("%s: No ISL6421 found!\n", __func__);
                                goto dettach_frontend;
@@ -1186,25 +1355,25 @@ static int dvb_init(struct saa7134_dev *dev)
                }
                break;
        case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
-               dev->dvb.frontend = dvb_attach(tda10046_attach,
+               fe0->dvb.frontend = dvb_attach(tda10046_attach,
                                               &medion_cardbus,
                                               &dev->i2c_adap);
-               if (dev->dvb.frontend) {
-                       dev->original_demod_sleep = dev->dvb.frontend->ops.sleep;
-                       dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
+               if (fe0->dvb.frontend) {
+                       dev->original_demod_sleep = fe0->dvb.frontend->ops.sleep;
+                       fe0->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
 
-                       dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+                       dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
                                   &dev->i2c_adap, medion_cardbus.tuner_address,
                                   TUNER_PHILIPS_FMD1216ME_MK3);
                }
                break;
        case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
-               dev->dvb.frontend = dvb_attach(tda10046_attach,
+               fe0->dvb.frontend = dvb_attach(tda10046_attach,
                                &philips_europa_config,
                                &dev->i2c_adap);
-               if (dev->dvb.frontend) {
-                       dev->dvb.frontend->ops.tuner_ops.init = philips_td1316_tuner_init;
-                       dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
+               if (fe0->dvb.frontend) {
+                       fe0->dvb.frontend->ops.tuner_ops.init = philips_td1316_tuner_init;
+                       fe0->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
                }
                break;
        case SAA7134_BOARD_CINERGY_HT_PCMCIA:
@@ -1243,15 +1412,15 @@ static int dvb_init(struct saa7134_dev *dev)
                        goto dettach_frontend;
                break;
        case SAA7134_BOARD_PHILIPS_SNAKE:
-               dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
+               fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
                                                &dev->i2c_adap);
-               if (dev->dvb.frontend) {
-                       if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
+               if (fe0->dvb.frontend) {
+                       if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60,
                                        &dev->i2c_adap, 0) == NULL) {
                                wprintk("%s: No tda826x found!\n", __func__);
                                goto dettach_frontend;
                        }
-                       if (dvb_attach(lnbp21_attach, dev->dvb.frontend,
+                       if (dvb_attach(lnbp21_attach, fe0->dvb.frontend,
                                        &dev->i2c_adap, 0, 0) == NULL) {
                                wprintk("%s: No lnbp21 found!\n", __func__);
                                goto dettach_frontend;
@@ -1273,24 +1442,24 @@ static int dvb_init(struct saa7134_dev *dev)
                saa7134_set_gpio(dev, 25, 0);
                msleep(10);
                saa7134_set_gpio(dev, 25, 1);
-               dev->dvb.frontend = dvb_attach(mt352_attach,
+               fe0->dvb.frontend = dvb_attach(mt352_attach,
                                                &avermedia_xc3028_mt352_dev,
                                                &dev->i2c_adap);
                attach_xc3028 = 1;
                break;
        case SAA7134_BOARD_MD7134_BRIDGE_2:
-               dev->dvb.frontend = dvb_attach(tda10086_attach,
+               fe0->dvb.frontend = dvb_attach(tda10086_attach,
                                                &sd1878_4m, &dev->i2c_adap);
-               if (dev->dvb.frontend) {
+               if (fe0->dvb.frontend) {
                        struct dvb_frontend *fe;
-                       if (dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
+                       if (dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
                                  &dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) {
                                wprintk("%s: MD7134 DVB-S, no SD1878 "
                                        "found !\n", __func__);
                                goto dettach_frontend;
                        }
                        /* we need to open the i2c gate (we know it exists) */
-                       fe = dev->dvb.frontend;
+                       fe = fe0->dvb.frontend;
                        fe->ops.i2c_gate_ctrl(fe, 1);
                        if (dvb_attach(isl6405_attach, fe,
                                        &dev->i2c_adap, 0x08, 0, 0) == NULL) {
@@ -1309,7 +1478,7 @@ static int dvb_init(struct saa7134_dev *dev)
                saa7134_set_gpio(dev, 25, 0);
                msleep(10);
                saa7134_set_gpio(dev, 25, 1);
-               dev->dvb.frontend = dvb_attach(mt352_attach,
+               fe0->dvb.frontend = dvb_attach(mt352_attach,
                                                &avermedia_xc3028_mt352_dev,
                                                &dev->i2c_adap);
                attach_xc3028 = 1;
@@ -1320,17 +1489,17 @@ static int dvb_init(struct saa7134_dev *dev)
                                                        &tda827x_cfg_2) < 0)
                                goto dettach_frontend;
                } else {                /* satellite */
-                       dev->dvb.frontend = dvb_attach(tda10086_attach,
+                       fe0->dvb.frontend = dvb_attach(tda10086_attach,
                                                &flydvbs, &dev->i2c_adap);
-                       if (dev->dvb.frontend) {
+                       if (fe0->dvb.frontend) {
                                if (dvb_attach(tda826x_attach,
-                                               dev->dvb.frontend, 0x60,
+                                               fe0->dvb.frontend, 0x60,
                                                &dev->i2c_adap, 0) == NULL) {
                                        wprintk("%s: Asus Tiger 3in1, no "
                                                "tda826x found!\n", __func__);
                                        goto dettach_frontend;
                                }
-                               if (dvb_attach(lnbp21_attach, dev->dvb.frontend,
+                               if (dvb_attach(lnbp21_attach, fe0->dvb.frontend,
                                                &dev->i2c_adap, 0, 0) == NULL) {
                                        wprintk("%s: Asus Tiger 3in1, no lnbp21"
                                                " found!\n", __func__);
@@ -1339,6 +1508,79 @@ static int dvb_init(struct saa7134_dev *dev)
                        }
                }
                break;
+       case SAA7134_BOARD_ASUSTeK_TIGER:
+               if (configure_tda827x_fe(dev, &philips_tiger_config,
+                                        &tda827x_cfg_0) < 0)
+                       goto dettach_frontend;
+               break;
+       case SAA7134_BOARD_BEHOLD_H6:
+               fe0->dvb.frontend = dvb_attach(zl10353_attach,
+                                               &behold_h6_config,
+                                               &dev->i2c_adap);
+               if (fe0->dvb.frontend) {
+                       dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
+                                  &dev->i2c_adap, 0x61,
+                                  TUNER_PHILIPS_FMD1216MEX_MK3);
+               }
+               break;
+       case SAA7134_BOARD_BEHOLD_X7:
+               fe0->dvb.frontend = dvb_attach(zl10353_attach,
+                                               &behold_x7_config,
+                                               &dev->i2c_adap);
+               if (fe0->dvb.frontend) {
+                       dvb_attach(xc5000_attach, fe0->dvb.frontend,
+                                  &dev->i2c_adap, &behold_x7_tunerconfig);
+               }
+               break;
+       case SAA7134_BOARD_AVERMEDIA_A700_PRO:
+       case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
+               /* Zarlink ZL10313 */
+               fe0->dvb.frontend = dvb_attach(mt312_attach,
+                       &avertv_a700_mt312, &dev->i2c_adap);
+               if (fe0->dvb.frontend) {
+                       if (dvb_attach(zl10036_attach, fe0->dvb.frontend,
+                                       &avertv_a700_tuner, &dev->i2c_adap) == NULL) {
+                               wprintk("%s: No zl10036 found!\n",
+                                       __func__);
+                       }
+               }
+               break;
+       case SAA7134_BOARD_VIDEOMATE_S350:
+               fe0->dvb.frontend = dvb_attach(mt312_attach,
+                               &zl10313_compro_s350_config, &dev->i2c_adap);
+               if (fe0->dvb.frontend)
+                       if (dvb_attach(zl10039_attach, fe0->dvb.frontend,
+                                       0x60, &dev->i2c_adap) == NULL)
+                               wprintk("%s: No zl10039 found!\n",
+                                       __func__);
+
+               break;
+       case SAA7134_BOARD_ZOLID_HYBRID_PCI:
+               fe0->dvb.frontend = dvb_attach(tda10048_attach,
+                                              &zolid_tda10048_config,
+                                              &dev->i2c_adap);
+               if (fe0->dvb.frontend != NULL) {
+                       dvb_attach(tda829x_attach, fe0->dvb.frontend,
+                                  &dev->i2c_adap, 0x4b,
+                                  &tda829x_no_probe);
+                       dvb_attach(tda18271_attach, fe0->dvb.frontend,
+                                  0x60, &dev->i2c_adap,
+                                  &zolid_tda18271_config);
+               }
+               break;
+       case SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S:
+               fe0->dvb.frontend = dvb_attach(tda10048_attach,
+                                              &dtv1000s_tda10048_config,
+                                              &dev->i2c_adap);
+               if (fe0->dvb.frontend != NULL) {
+                       dvb_attach(tda829x_attach, fe0->dvb.frontend,
+                                  &dev->i2c_adap, 0x4b,
+                                  &tda829x_no_probe);
+                       dvb_attach(tda18271_attach, fe0->dvb.frontend,
+                                  0x60, &dev->i2c_adap,
+                                  &dtv1000s_tda18271_config);
+               }
+               break;
        default:
                wprintk("Huh? unknown DVB card?\n");
                break;
@@ -1351,10 +1593,10 @@ static int dvb_init(struct saa7134_dev *dev)
                        .i2c_addr  = 0x61,
                };
 
-               if (!dev->dvb.frontend)
-                       return -1;
+               if (!fe0->dvb.frontend)
+                       goto dettach_frontend;
 
-               fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg);
+               fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
                if (!fe) {
                        printk(KERN_ERR "%s/2: xc3028 attach failed\n",
                               dev->name);
@@ -1362,38 +1604,44 @@ static int dvb_init(struct saa7134_dev *dev)
                }
        }
 
-       if (NULL == dev->dvb.frontend) {
+       if (NULL == fe0->dvb.frontend) {
                printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name);
-               return -1;
+               goto dettach_frontend;
        }
+       /* define general-purpose callback pointer */
+       fe0->dvb.frontend->callback = saa7134_tuner_callback;
 
        /* register everything else */
-       ret = videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev,
-                                   adapter_nr);
+       ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
+                                       &dev->pci->dev, adapter_nr, 0, NULL);
 
        /* this sequence is necessary to make the tda1004x load its firmware
         * and to enter analog mode of hybrid boards
         */
        if (!ret) {
-               if (dev->dvb.frontend->ops.init)
-                       dev->dvb.frontend->ops.init(dev->dvb.frontend);
-               if (dev->dvb.frontend->ops.sleep)
-                       dev->dvb.frontend->ops.sleep(dev->dvb.frontend);
-               if (dev->dvb.frontend->ops.tuner_ops.sleep)
-                       dev->dvb.frontend->ops.tuner_ops.sleep(dev->dvb.frontend);
+               if (fe0->dvb.frontend->ops.init)
+                       fe0->dvb.frontend->ops.init(fe0->dvb.frontend);
+               if (fe0->dvb.frontend->ops.sleep)
+                       fe0->dvb.frontend->ops.sleep(fe0->dvb.frontend);
+               if (fe0->dvb.frontend->ops.tuner_ops.sleep)
+                       fe0->dvb.frontend->ops.tuner_ops.sleep(fe0->dvb.frontend);
        }
        return ret;
 
 dettach_frontend:
-       if (dev->dvb.frontend)
-               dvb_frontend_detach(dev->dvb.frontend);
-       dev->dvb.frontend = NULL;
-
-       return -1;
+       videobuf_dvb_dealloc_frontends(&dev->frontends);
+       return -EINVAL;
 }
 
 static int dvb_fini(struct saa7134_dev *dev)
 {
+       struct videobuf_dvb_frontend *fe0;
+
+       /* Get the first frontend */
+       fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
+       if (!fe0)
+               return -EINVAL;
+
        /* FIXME: I suspect that this code is bogus, since the entry for
           Pinnacle 300I DVB-T PAL already defines the proper init to allow
           the detection of mt2032 (TDA9887_PORT2_INACTIVE)
@@ -1406,14 +1654,14 @@ static int dvb_fini(struct saa7134_dev *dev)
                tda9887_cfg.priv  = &on;
 
                /* otherwise we don't detect the tuner on next insmod */
-               saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tda9887_cfg);
+               saa_call_all(dev, tuner, s_config, &tda9887_cfg);
        } else if (dev->board == SAA7134_BOARD_MEDION_MD8800_QUADRO) {
                if ((dev->eedata[2] == 0x07) && use_frontend) {
                        /* turn off the 2nd lnb supply */
                        u8 data = 0x80;
                        struct i2c_msg msg = {.addr = 0x08, .buf = &data, .flags = 0, .len = 1};
                        struct dvb_frontend *fe;
-                       fe = dev->dvb.frontend;
+                       fe = fe0->dvb.frontend;
                        if (fe->ops.i2c_gate_ctrl) {
                                fe->ops.i2c_gate_ctrl(fe, 1);
                                i2c_transfer(&dev->i2c_adap, &msg, 1);
@@ -1421,8 +1669,7 @@ static int dvb_fini(struct saa7134_dev *dev)
                        }
                }
        }
-       if (dev->dvb.frontend)
-               videobuf_dvb_unregister(&dev->dvb);
+       videobuf_dvb_unregister_bus(&dev->frontends);
        return 0;
 }